This is the code of servlet which handles errors at the web server:
public class GeneralErrorServlet extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String referer = request.getHeader("Referer");
String url = String.valueOf(request.getAttribute("javax.servlet.error.request_uri"));
String queryString = request.getQueryString();
String statusCode = String.valueOf(request.getAttribute("javax.servlet.error.status_code"));
String message = String.valueOf(request.getAttribute("javax.servlet.error.message"));
Throwable throwable = (Throwable) request.getAttribute("javax.servlet.error.exception");
if (referer != null && !"null".equals(referer) && !referer.contains("googleads.g.doubleclick.net/pagead")) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,
"GENERAL ERROR MESSAGE: requestUrl= {0}, referer:{1}, statusCode={2}, message = {3}", new Object[]{url, referer, statusCode, message});
} else {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,
"GENERAL ERROR MESSAGE: requestUrl= {0} , statusCode={1}, message = {2}", new Object[]{url, statusCode, message});
}
if (throwable != null) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "ERROR CAUSE:" + throwable.getMessage(), throwable);
}
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
// rest omitted since the previous line creates problems
The problem is that I see frequently in my server.logs in a production environment that response stream has already been used but I cannot reproduce it in localhost (error message usually works). Any idea what to do around that problem?
This is the example of what I see frequently in a production log:
Servlet.service() for servlet GeneralErrorServlet threw exception
java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:777)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:224)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:152)
at common.GeneralErrorServlet.processRequest(GeneralErrorServlet.java:48)
at common.GeneralErrorServlet.doGet(GeneralErrorServlet.java:110)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.ApplicationDispatcher.doInvoke(ApplicationDispatcher.java:875)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:739)
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:695)
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:626)
FYI, This is how is this error servlet mapped:
<servlet-mapping>
<servlet-name>GeneralErrorServlet</servlet-name>
<url-pattern>/common/general_error</url-pattern>
</servlet-mapping>
<error-page>
<error-code>404</error-code>
<location>/common/general_error</location>
</error-page>
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/common/general_error</location>
</error-page>
I know this question is long, but I don't know to explain it better and shorter at the moment.