Mantis - Resin
Viewing Issue Advanced Details
989 minor always 03-13-06 14:32 04-13-06 10:59
closed 3.0.18  
none 3.0.19  
0000989: JSP wrapper issue
(rep by Tony Field)

I am wrapping a ServletResponse, then am creating a request dispatcher and then including a standard JSP using my wrapped response:

My servlet uses a manager class to handle includes. Here is the interesting code:

    public ServletRRManager(HttpServlet servlet, HttpServletRequest request, HttpServletResponse response)
        this.servlet = servlet;
        this.request = new MyHttpServletRequest(request);
        responseStack = new Stack<MyHttpServletResponse>();
        responseStack.push(new MyHttpServletResponse(response));
    public void include(String path) throws IncludeException
        RequestDispatcher rd = request.getRequestDispatcher(path);
            MyHttpServletResponse res = responseStack.peek();
            rd.include(request, res);
        catch (Exception e)
            throw new IncludeException("Failure including resource at " + path, e);


My wrapper class is really simple - basically it captures the output of the getWriter() content in a StringWriter and the getOutputStream() content in a ByteArrayOutputStream. My wrapper has accessor methods for this data and I process it before streaming it to the actual response (this processing is effectively the ultimate goal of the whole pile of code - we are refactoring our caching engine).

I have noticed that I can't include a JSP if I have already grabbed the outputStream because the JSP will always try to grab the writer. This seems reasonable.

However, if my caller grabs the writer instead, then includes a JSP, then tries to either write to the writer again or grab it again from the response wrapper, it fails because somewhere in the JSP include code the checkError() flag of the PrintWriter has been set: it seems that including a JSP "corrupts" my PrintWriter.

03-17-06 20:17   
Basically, in the com.caucho.jsp.Page.pageservice() method, after determining that the response is not a CauchoResponse it is wrapped then it executes the service() method in a try block. In the finally block the "response" is closed, and this closes the underlying stream and ultimately my printwriter.

You probably do want to close your wrapper but I don't think it makes sense to close the underlying writer, do you?.

Here is the stack trace that shows you where the close() call is happening that should not be happening:

java.lang.Exception: Stack trace
    at java.lang.Thread.dumpStack(
    at com.fatwire.cs.reqres.servlet.CSHttpServletResponse$CSPrintWriter.close(
    at com.caucho.server.connection.ToCharResponseAdapter$ToCharResponseStreamWrapper.close(
    at com.caucho.server.connection.ResponseAdapter.close(
--> at com.caucho.jsp.Page.pageservice(
    at com.caucho.server.dispatch.PageFilterChain.doFilter(
    at com.caucho.server.webapp.DispatchFilterChain.doFilter(
    at com.caucho.server.dispatch.ServletInvocation.service(
    at com.caucho.server.webapp.RequestDispatcherImpl.include(
    at com.caucho.server.webapp.RequestDispatcherImpl.include(
    at com.fatwire.cs.reqres.servlet.ServletRRManager.include(
    at com.fatwire.cs.reqres.servlet.TestServlet.doGet(
    at javax.servlet.http.HttpServlet.service(
    at javax.servlet.http.HttpServlet.service(
    at com.caucho.server.dispatch.ServletFilterChain.doFilter(
    at com.caucho.server.webapp.WebAppFilterChain.doFilter(
    at com.caucho.server.dispatch.ServletInvocation.service(
    at com.caucho.server.http.HttpRequest.handleRequest(
    at com.caucho.util.ThreadPool.runTasks(
04-13-06 10:59