tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Derek Richardson" <Derek.Richard...@appiancorp.com>
Subject Wrapping response causing premature stream closure
Date Thu, 15 Jan 2004 22:27:40 GMT
I am attempting to wrap the HttpServletResponse to apply gzip compression on data sent to the
client when gzip is supported. I have written a filter (based on published code) that works
fine with static content. I, however, have a problem when applying it to dynamic content.
The dynamic content is written using Struts and it seems to be breaking during the tiles includes.
However, struts does not seem to be the culprit - the same code works fine without the filter.

The problem is straightforward - I receive a "java.io.IOException: Stream closed" message.
I am not including the stack trace because, in my mind (which I am out of with frustration
at this moment), the problem is not where the closed stream is detected, but where it is closed.
I placed a log statement in my wrapper to dump a stack trace when close() is called and this
stack trace is included below. It seems that close() is being called from org.apache.catalina.core.ApplicationDispatcher.doForward().
But my confusion is how my wrapper could be causing this closure, since the application works
fine without the wrapper.

My question is: what could I be doing in the request or output stream wrappers that would
cause the stream to be closed?

The wrapper source code is also below.

Thanks,

Derek Richardson

********************************************************************************

2004-01-15 16:34:21,092 [http8080-Processor3] DEBUG com.appiancorp.ap2.Compressi
onResponseStream - ^^^^^^^^^^^^^^^^^^^^^^^^ Closing...
java.lang.Exception
        at com.appiancorp.ap2.CompressionResponseStream.close(Unknown Source)
        at sun.nio.cs.StreamEncoder$CharsetSE.implClose(StreamEncoder.java:431)
        at sun.nio.cs.StreamEncoder.close(StreamEncoder.java:160)
        at java.io.OutputStreamWriter.close(OutputStreamWriter.java:222)
        at java.io.PrintWriter.close(PrintWriter.java:137)
        at org.apache.jasper.runtime.JspWriterImpl.close(JspWriterImpl.java:223)

        at java.io.PrintWriter.close(PrintWriter.java:137)
        at org.apache.jasper.runtime.JspWriterImpl.close(JspWriterImpl.java:223)

        at java.io.PrintWriter.close(PrintWriter.java:137)
        at org.apache.jasper.runtime.JspWriterImpl.close(JspWriterImpl.java:223)

        at java.io.PrintWriter.close(PrintWriter.java:137)
        at org.apache.jasper.runtime.JspWriterImpl.close(JspWriterImpl.java:223)

        at java.io.PrintWriter.close(PrintWriter.java:137)
        at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationD
ispatcher.java:453)
        at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDis
patcher.java:356)
        at org.apache.struts.action.RequestProcessor.doForward(RequestProcessor.
java:1069)
        at org.apache.struts.tiles.TilesRequestProcessor.doForward(TilesRequestP
rocessor.java:274)
        at org.apache.struts.action.RequestProcessor.processForwardConfig(Reques
tProcessor.java:455)
        at org.apache.struts.tiles.TilesRequestProcessor.processForwardConfig(Ti
lesRequestProcessor.java:320)
        at org.apache.struts.action.RequestProcessor.process(RequestProcessor.ja
va:279)
        at org.apache.struts.action.ActionServlet.process(ActionServlet.java:148
2)
        at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525)

        at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDisp
atcher.java:684)
        at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationD
ispatcher.java:575)
        at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDis
patcher.java:498)
        at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary
.java:822)
        at org.apache.jasper.runtime.PageContextImpl.include(PageContextImpl.jav
a:398)
        at org.apache.struts.tiles.TilesUtilImpl.doInclude(TilesUtilImpl.java:13
7)
        at org.apache.struts.tiles.TilesUtil.doInclude(TilesUtil.java:177)
        at org.apache.struts.taglib.tiles.InsertTag.doInclude(InsertTag.java:756
)
        at org.apache.struts.taglib.tiles.InsertTag$InsertHandler.doEndTag(Inser
tTag.java:881)
        at org.apache.struts.taglib.tiles.InsertTag.doEndTag(InsertTag.java:473)

        at org.apache.jsp.portlet_default_jsp._jspx_meth_t_insert_0(portlet_defa
ult_jsp.java:1099)
        at org.apache.jsp.portlet_default_jsp._jspService(portlet_default_jsp.ja
va:364)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:137)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper
.java:210)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:2
95)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:241)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDisp
atcher.java:684)
        at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationD
ispatcher.java:575)
        at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDis
patcher.java:498)
        at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary
.java:822)
        at org.apache.jasper.runtime.PageContextImpl.include(PageContextImpl.jav
a:398)
        at org.apache.struts.tiles.TilesUtilImpl.doInclude(TilesUtilImpl.java:13
7)
        at org.apache.struts.tiles.TilesUtil.doInclude(TilesUtil.java:177)
        at org.apache.struts.taglib.tiles.InsertTag.doInclude(InsertTag.java:756
)
        at org.apache.struts.taglib.tiles.InsertTag$InsertHandler.doEndTag(Inser
tTag.java:881)
        at org.apache.struts.taglib.tiles.InsertTag.doEndTag(InsertTag.java:473)

        at org.apache.jsp.portletarea_jsp._jspService(portletarea_jsp.java:275)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:137)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper
.java:210)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:2
95)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:241)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDisp
atcher.java:684)
        at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationD
ispatcher.java:575)
        at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDis
patcher.java:498)
        at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary
.java:822)
        at org.apache.jasper.runtime.PageContextImpl.include(PageContextImpl.jav
a:398)
        at org.apache.struts.tiles.TilesUtilImpl.doInclude(TilesUtilImpl.java:13
7)
        at org.apache.struts.tiles.TilesUtil.doInclude(TilesUtil.java:177)
        at org.apache.struts.taglib.tiles.InsertTag.doInclude(InsertTag.java:756
)
        at org.apache.struts.taglib.tiles.InsertTag$InsertHandler.doEndTag(Inser
tTag.java:881)
        at org.apache.struts.taglib.tiles.InsertTag.doEndTag(InsertTag.java:473)

        at org.apache.jsp.template_default_jsp._jspx_meth_t_insert_3(template_de
fault_jsp.java:785)
        at org.apache.jsp.template_default_jsp._jspService(template_default_jsp.
java:357)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:137)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper
.java:210)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:2
95)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:241)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDisp
atcher.java:684)
        at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationD
ispatcher.java:575)
        at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDis
patcher.java:498)
        at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary
.java:822)
        at org.apache.jasper.runtime.PageContextImpl.include(PageContextImpl.jav
a:398)
        at org.apache.struts.tiles.TilesUtilImpl.doInclude(TilesUtilImpl.java:13
7)
        at org.apache.struts.tiles.TilesUtil.doInclude(TilesUtil.java:177)
        at org.apache.struts.taglib.tiles.InsertTag.doInclude(InsertTag.java:756
)
        at org.apache.struts.taglib.tiles.InsertTag$InsertHandler.doEndTag(Inser
tTag.java:881)
        at org.apache.struts.taglib.tiles.InsertTag.doEndTag(InsertTag.java:473)

        at org.apache.jsp.portal_jsp._jspx_meth_t_insert_0(portal_jsp.java:133)
        at org.apache.jsp.portal_jsp._jspService(portal_jsp.java:104)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:137)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
        at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper
.java:210)
        at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:2
95)
        at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:241)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDisp
atcher.java:684)
        at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationD
ispatcher.java:432)
        at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDis
patcher.java:356)
        at org.apache.struts.action.RequestProcessor.doForward(RequestProcessor.
java:1069)
        at org.apache.struts.tiles.TilesRequestProcessor.doForward(TilesRequestP
rocessor.java:274)
        at org.apache.struts.action.RequestProcessor.processForwardConfig(Reques
tProcessor.java:455)
        at org.apache.struts.tiles.TilesRequestProcessor.processForwardConfig(Ti
lesRequestProcessor.java:320)
        at org.apache.struts.action.RequestProcessor.process(RequestProcessor.ja
va:279)
        at org.apache.struts.action.ActionServlet.process(ActionServlet.java:148
2)
        at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525)

        at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDisp
atcher.java:684)
        at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationD
ispatcher.java:432)
        at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDis
patcher.java:356)
        at org.apache.struts.action.RequestProcessor.doForward(RequestProcessor.
java:1069)
        at org.apache.struts.tiles.TilesRequestProcessor.doForward(TilesRequestP
rocessor.java:274)
        at org.apache.struts.action.RequestProcessor.processForwardConfig(Reques
tProcessor.java:455)
        at org.apache.struts.tiles.TilesRequestProcessor.processForwardConfig(Ti
lesRequestProcessor.java:320)
        at org.apache.struts.action.RequestProcessor.process(RequestProcessor.ja
va:279)
        at org.apache.struts.action.ActionServlet.process(ActionServlet.java:148
2)
        at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525)

        at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDisp
atcher.java:684)
        at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationD
ispatcher.java:432)
        at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDis
patcher.java:356)
        at org.apache.struts.action.RequestProcessor.doForward(RequestProcessor.
java:1069)
        at org.apache.struts.tiles.TilesRequestProcessor.doForward(TilesRequestP
rocessor.java:274)
        at org.apache.struts.action.RequestProcessor.processForwardConfig(Reques
tProcessor.java:455)
        at org.apache.struts.tiles.TilesRequestProcessor.processForwardConfig(Ti
lesRequestProcessor.java:320)
        at org.apache.struts.action.RequestProcessor.process(RequestProcessor.ja
va:279)
        at org.apache.struts.action.ActionServlet.process(ActionServlet.java:148
2)
        at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525)

        at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDisp
atcher.java:684)
        at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationD
ispatcher.java:432)
        at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDis
patcher.java:356)
        at org.apache.struts.action.RequestProcessor.doForward(RequestProcessor.
java:1069)
        at org.apache.struts.tiles.TilesRequestProcessor.doForward(TilesRequestP
rocessor.java:274)
        at org.apache.struts.action.RequestProcessor.processForwardConfig(Reques
tProcessor.java:455)
        at org.apache.struts.tiles.TilesRequestProcessor.processForwardConfig(Ti
lesRequestProcessor.java:320)
        at org.apache.struts.action.RequestProcessor.process(RequestProcessor.ja
va:279)
        at org.apache.struts.action.ActionServlet.process(ActionServlet.java:148
2)
        at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525)

        at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
icationFilterChain.java:247)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
ilterChain.java:193)
        at com.appiancorp.ap2.EntryFilter.doFilter(Unknown Source)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
icationFilterChain.java:213)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
ilterChain.java:193)
        at com.appiancorp.ap2.AuthenticationFilter.doFilter(Unknown Source)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
icationFilterChain.java:213)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
ilterChain.java:193)
        at com.appiancorp.ap2.WrapFilter.doFilter(Unknown Source)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
icationFilterChain.java:213)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
ilterChain.java:193)
        at com.appiancorp.ap2.CompressionFilter.doFilter(Unknown Source)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
icationFilterChain.java:213)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
ilterChain.java:193)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperV
alve.java:256)
        at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContex
t.invokeNext(StandardPipeline.java:643)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav
a:480)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)

        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextV
alve.java:191)
        at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContex
t.invokeNext(StandardPipeline.java:643)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav
a:480)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)

        at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:
2417)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.j
ava:180)
        at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContex
t.invokeNext(StandardPipeline.java:643)
        at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatche
rValve.java:171)
        at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContex
t.invokeNext(StandardPipeline.java:641)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.j
ava:172)
        at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContex
t.invokeNext(StandardPipeline.java:641)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav
a:480)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)

        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineVal
ve.java:174)
        at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContex
t.invokeNext(StandardPipeline.java:643)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.jav
a:480)
        at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995)

        at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:19
3)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java
:781)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.proce
ssConnection(Http11Protocol.java:549)
        at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java
:589)
        at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadP
ool.java:666)
        at java.lang.Thread.run(Thread.java:534)

********************************************************************************

package com.appiancorp.ap2;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

import org.apache.log4j.Logger;

public class CompressionResponseWrapper extends HttpServletResponseWrapper {
  protected ServletOutputStream stream = null;
  protected PrintWriter writer = null;

  public CompressionResponseWrapper(HttpServletResponse response) {
    super(response);
  }

  public ServletOutputStream createOutputStream() throws IOException {
    return new CompressionResponseStream((HttpServletResponse)getResponse());
  }

  public void finishResponse() {
    if (_log.isDebugEnabled()) _log.error("In finishResponse()");
    if (writer != null) writer.close();
    else {
      try {
        if (stream != null) stream.close();
      } catch (IOException e) {
        if (_log.isDebugEnabled()) _log.error("Couldn't close stream",e);
      }
    }
  }

  public void flushBuffer() throws IOException {
    stream.flush();
  }

  public ServletOutputStream getOutputStream() throws IOException {
    if (stream != null) return stream;
    if (writer != null) {
      throw new IllegalStateException("getWriter() has already been called!");
    }
    stream = createOutputStream();
    return stream;
  }

  public PrintWriter getWriter() throws IOException {
    if (writer != null) return writer;
    if (stream != null) {
      throw new IllegalStateException("getOutputStream() has already been called!");
    }
    stream = createOutputStream();
    writer = new PrintWriter(new OutputStreamWriter(stream, "UTF-8"));
    return writer;
  }

  public void setContentLength(int length) { /* noop - set in stream.close() */ }
  private static Logger _log = Logger.getLogger(CompressionResponseWrapper.class);
}

********************************************************************************

package com.appiancorp.ap2;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

public class CompressionResponseStream extends ServletOutputStream {
  protected ByteArrayOutputStream baos = null;
  protected GZIPOutputStream gzipstream = null;
  protected boolean closed = false;
  protected HttpServletResponse response = null;
  protected ServletOutputStream output = null;

  public CompressionResponseStream(HttpServletResponse response)
    throws IOException {
    super();
    closed = false;
    this.response = response;
    this.output = response.getOutputStream();
    baos = new ByteArrayOutputStream();
    gzipstream = new GZIPOutputStream(baos);
  }

  public void close() throws IOException {
    if (_log.isDebugEnabled()) _log.debug("^^^^^^^^^^^^^^^^^^^^^^^^ Closing...", new Exception());
    if (closed) {
      _log.warn("This output stream has already been closed");
      //throw new IOException("This output stream has already been closed");
      return;
    }
    gzipstream.finish();

    byte[] bytes = baos.toByteArray();

    response.addHeader("Content-Length", Integer.toString(bytes.length));
    response.addHeader("Content-Encoding", "gzip");
    output.write(bytes);
    output.flush();
    output.close();
    closed = true;
  }

  public void flush() throws IOException {
    if (closed) {
      throw new IOException("Cannot flush a closed output stream");
    }
    gzipstream.flush();
  }

  public void write(int b) throws IOException {
    if (closed) {
      throw new IOException("Cannot write to a closed output stream");
    }
    gzipstream.write((byte) b);
  }

  public void write(byte b[]) throws IOException {
    write(b, 0, b.length);
  }

  public void write(byte b[], int off, int len) throws IOException {
    if (closed) {
      throw new IOException("Cannot write to a closed output stream");
    }
    gzipstream.write(b, off, len);
  }

  public boolean closed() {
    return (this.closed);
  }

  public void reset() {
    if (_log.isDebugEnabled()) _log.debug("*************************** reset");
    //noop
  }
  private static Logger _log = Logger.getLogger(CompressionResponseStream.class);
}

---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-user-help@jakarta.apache.org


Mime
View raw message