Menu

#19 Exception when processing "jsp:forward" tag in WebLogic

open-rejected
5
2012-01-19
2012-01-19
Anonymous
No

I'm using pjl-comp-filter-1.7.zip with WebLogic 11gR1 (10.3.5) and the following exception is thrown when processing "jsp:forward" tag (and also when forwarding by <%@ page errorPage="xxx.jsp" %>).

java.lang.IllegalStateException: Can't reset
at com.planetj.servlet.filter.compression.ThresholdOutputStream.reset(ThresholdOutputStream.java:141)
at com.planetj.servlet.filter.compression.CompressingServletOutputStream.reset(CompressingServletOutputStream.java:110)
at com.planetj.servlet.filter.compression.CompressingHttpServletResponse.resetBuffer(CompressingHttpServletResponse.java:230)
at weblogic.servlet.internal.DelegateChunkWriter.clearBuffer(DelegateChunkWriter.java:127)
at weblogic.servlet.internal.ChunkOutputWrapper.clearBuffer(ChunkOutputWrapper.java:184)
at weblogic.servlet.jsp.JspWriterImpl.clear(JspWriterImpl.java:84)
at weblogic.servlet.jsp.PageContextImpl.forward(PageContextImpl.java:155)
at jsp_servlet.__grouplist._jspService(__grouplist.java:288)
at weblogic.servlet.jsp.JspBase.service(JspBase.java:34)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:300)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at com.erapidsuite.configurator.SessionFilter.doFilter(SessionFilter.java:160)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at com.planetj.servlet.filter.compression.CompressingFilter.doFilter(CompressingFilter.java:270)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3715)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3681)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2277)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2183)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1454)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)

Discussion

  • Sean Owen

    Sean Owen - 2012-01-19
    • status: open --> open-rejected
     
  • Sean Owen

    Sean Owen - 2012-01-19

    It looks like the response has already been committed by writing output earlier. Then on forward, it tries to un-write output that's already gone to the client but can't, since it has been sent.

    This is a problem, in general, in J2EE -- you can't clear or reset after the response is committed. Based on this alone it's not related to the filter.

    However in certain settings the filter will begin committing straight away after your first output (like when you force compression). The first write commits the response. Whereas without the filter often the default container behavior buffers the output, so you can get away with (techincally incorrectly) writing some output and then clearing it.

    I would recommend ensuring that you write no output before the forward tag, not even white space or newlines. Or reopen with some more info that indicates this is really a filter issue.

     
  • Nobody/Anonymous

    Your explanation is really helpful, thank you. I've verified that everything works fine when I put the forward tag in the beginning of the jsp file.

    However, the actual issue is triggered by the use of <%@ page errorPage="error.jsp" %>. Before using the compressing filter, WebLogic forwarded to "error.jsp" page when there is an exception. From the stack trace below, I believe that the logic in weblogic.servlet.jsp.PageContextImpl.handlePageException() issues the forward command which results in clearing buffer in the output stream chain. I currently cannot find the way to avoid this thing.

    I have also tried "WebLogic Compression Filter" described in http://www.developer.com/java/ent/article.php/10933_3833381_2/Compressing-Server-Responses-in-Java-Enterprise-Applications.htm, and there is no exception; however, the response is compressed twice instead !

    java.lang.IllegalStateException: Can't reset
    at com.planetj.servlet.filter.compression.ThresholdOutputStream.reset(ThresholdOutputStream.java:141)
    at com.planetj.servlet.filter.compression.CompressingServletOutputStream.reset(CompressingServletOutputStream.java:110)
    at com.planetj.servlet.filter.compression.CompressingHttpServletResponse.resetBuffer(CompressingHttpServletResponse.java:230)
    at weblogic.servlet.internal.DelegateChunkWriter.clearBuffer(DelegateChunkWriter.java:127)
    at weblogic.servlet.internal.ChunkOutputWrapper.clearBuffer(ChunkOutputWrapper.java:184)
    at weblogic.servlet.jsp.JspWriterImpl.clear(JspWriterImpl.java:84)
    at weblogic.servlet.jsp.PageContextImpl.forward(PageContextImpl.java:155)
    at weblogic.servlet.jsp.PageContextImpl.handlePageException(PageContextImpl.java:403)
    at jsp_servlet.__grouplist._jspService(__grouplist.java:341)
    at weblogic.servlet.jsp.JspBase.service(JspBase.java:34)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:300)
    at weblogic.servlet.internal.ServletStubImpl.onAddToMapException(ServletStubImpl.java:416)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:326)
    at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
    at com.erapidsuite.configurator.SessionFilter.doFilter(SessionFilter.java:160)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
    at com.planetj.servlet.filter.compression.CompressingFilter.doFilter(CompressingFilter.java:270)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3715)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3681)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2277)
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2183)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1454)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)

     
  • Sean Owen

    Sean Owen - 2012-01-19

    Yes this has always been a problem with the JSP error page model IMHO.

    Try setting the filter to use a significantly larger buffer, so it will delay beginning its write to the client a lot longer. Really to solve this you have to buffer the whole response, to be sure it succeeded, before writing.

    (Of course you should also try to not rely on error.jsp -- it is just there in case something totally unexpected goes wrong. You should handle 'normal' error conditions yourself with some business logic, not punt to error.jsp)