Tomcat exception Cannot call sendError() after the response has been committed?

Viewed 97217

While doing some operations in my application I got

java.lang.IllegalStateException Cannot call sendError()

When I reload the page again it work some time properly, but after some time again it shows the same exception. How can I overcome this exception?

Below is the exception:

HTTP Status 500 - Cannot call sendError() after the response has been committed
type Exception report
message Cannot call sendError() after the response has been committed
description The server encountered an internal error that prevented it from fulfilling this request.
exception 
java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:451)
org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:725)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:485)
org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:395)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.40 logs.

Struts.xml

<struts>
    <package name="default" extends="hibernate-default">
        <action name="addUser" method="add" class="com.demo.action.UserAction">
            <result name="input">/register.jsp</result>
            <result name="success" type="redirect">list</result>
        </action>
        <action name="list" method="list" class="com.demo.action.UserAction">
            <interceptor-ref name="basicStackHibernate" />
            <result name="success">/list.jsp</result>
        </action>
    </package>
</struts>
14 Answers

I was creating a @ManyToOne and @OneToMany relationship. I added @JsonIgnore above the @ManyToOne and it solved the error.

For others in my situation--What was happening was that I had two @Entity objects with a many to many relationship causing infinite json to be generated, causing spring security to throw this error. Try adding @JsonIgnore above your hibernate relationships.

You can try this Annotation it will help as it fixed my issue.

It will definitely help if it will not be able to help you, then try to modify this as per your requirement.

@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
   @JsonIdentityReference(alwaysAsId=true)

Note: there are 2 @JsonIgnore dependencies you can import. Make sure it's from Jackson library; that made the difference for me:

import com.fasterxml.jackson.annotation.JsonIgnore;

This is what caused it in my case.

I have 2 filters that both have the capability to send an error through the HttpServletResponse.sendError() method. If Filter A discovered something wrong and called sendError on the HttpServletResponse object, then a second call in the same filter or in filter B will cause the cannot call senderror exception. This is because sendError does not cause the request itself to be aborted. The code in the filter continues to be executed after the sendError method had been called.

This is a common error and there can be various root cause can be identified. In my case I were opening pdf file from the web service and for this I were performing write operation in file using buffer. So kindly change below:

        File outfile = File.createTempFile("temp", ".pdf");

        OutputStream os=new FileOutputStream(outfile);
        byte[] buffer = new byte[1024];

        int length;
        /*copying the contents from input stream to
         * output stream using read and write methods
         */
        while ((length = is.read(buffer)) > 0){
            os.write(buffer, 0, length);
        }

to

        File outfile = File.createTempFile("temp", ".pdf");
        IOUtils.copy(is, new FileOutputStream(outfile));

and after this I were performing below operation:

    javax.ws.rs.core.Response.ResponseBuilder responseBuilder = javax.ws.rs.core.Response
                .ok(outfile, MediaType.APPLICATION_OCTET_STREAM);
                responseBuilder.header("content-type","application/pdf");

             return responseBuilder.build();

and error get resolved. Cheers!

There are so many answers to use @JsonIgnore annotation. But I will not recommend it. If your parent class has a many-to-one relationship with a single entity then it is fine. But if your parent class has multiple many-to-one relationships then definitely it gives a headache to you.

I will suggest going with a uni-directional approach and implement a separate dto class based on your requirement.

@JsonIgnore on the @ManyToOne mapping will resolve it.

I was using Jersey and I returned the following response

Response.status(HttpStatus.SC_MOVED_TEMPORARILY).header("Location", "https://example.com?param1=foo bar").build()

After URL encoding, the issue was solved

Response.status(HttpStatus.SC_MOVED_TEMPORARILY).header("Location", "https://example.com?param1=foo%20bar").build()
Related