Hi,
We are running Tomcat 6. 0.32 with jdk1.6.0_26 on Solaris 10, mod_ajp and A=
pache 2.2.21 in our production environment and are looking to upgrade to To=
mcat 7 but have run into a problem with the CompressionFilter (an older ver=
sion of the Amy Roh one) causing this exception:
SEVERE: Servlet.service() for servlet [jsp] in context with path [] threw e=
xception [java.lang.IllegalStateException: getWriter() has already been cal=
led for this response] with root cause
java.lang.IllegalStateException: getWriter() has already been called for th=
is response
at org.apache.catalina.connector.Response.getOutputStream(Response.=
java:594)
at org.apache.catalina.connector.ResponseFacade.getOutputStream(Res=
ponseFacade.java:199)
at com.tirerack.filters.CompressionResponseStream.<init>(Compressio=
nResponseStream.java:47)
at com.tirerack.filters.CompressionServletResponseWrapper.createOut=
putStream(CompressionServletResponseWrapper.java:172)
at com.tirerack.filters.CompressionServletResponseWrapper.getWriter=
(CompressionServletResponseWrapper.java:250)
at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.ja=
va:125)
at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImp=
l.java:118)
at org.apache.jasper.runtime.PageContextImpl.release(PageContextImp=
l.java:190)
at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageCont=
ext(JspFactoryImpl.java:123)
at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspF=
actoryImpl.java:80)
at org.apache.jsp.upgrade_005fgarage.SetCurrentVehicle_jsp._jspServ=
ice(SetCurrentVehicle_jsp.java:278)
These appear to occur when the "response.sendRedirect("/page.jsp")" is used=
on a JSP. The error is caught and handled so the customer doesn't notice i=
t and is still redirected, but it sure generates a ton of log entries and I=
'd like to get it fixed before proceeding with our upgrade.
I saw that another user had trouble (copied post snippet below for referenc=
e) with the new flushBuffer() call that was added to the Response.java for =
sendRedirect() in 7.0.21 and I'm guessing that's the issue here, too, but I=
'm not sure how to get around it.
>From what I've read, you can only use a getWriter or a getOutputStream on a=
single response object, not both, and I think this error is happening beca=
use the flushBuffer() method that was added is invoking the getWriter on li=
ne 118 (http://www.docjar.com/html/api/org/apache/jasper/runtime/JspWriterI=
mpl.java.html) when an output stream was already being used:
111 protected final void flushBuffer() throws IOException {
112 if (bufferSize =3D=3D 0)
113 return;
114 flushed =3D true;
115 ensureOpen();
116 if (nextChar =3D=3D 0)
117 return;
--> 118 initOut();
119 out.write(cb, 0, nextChar);
120 nextChar =3D 0;
121 }
122
123 private void initOut() throws IOException {
124 if (out =3D=3D null) {
-->125 out =3D response.getWriter();
126 }
127 }
We have several other filters in place and the error goes away by removing =
just the CompressionFilter, so the issue is definitely in that one filter.
Since this is a pretty common filter, I'm hoping someone else has run into =
this and has found a fix. Anyone?
-Kari
Begin forwarded message:
From: Jacob Champlin <jacobc@rentec.com<mailto:jacobc@rentec.com>>
Date: September 27, 2011 1:55:39 PM CDT
To: <users@tomcat.apache.org<mailto:users@tomcat.apache.org>>
Subject: Re: 7.0.21 Redirects failing randomly
Reply-To: Tomcat Users List <users@tomcat.apache.org<mailto:users@tomcat.ap=
ache.org>>
Konstantin,
Ok, so I see now why you added the flushBuffer() from spec:
http://java.sun.com/javaee/6/docs/api/javax/servlet/http/HttpServletRespons=
e.html#sendRedirect%28java.lang.String%29
"Sends a temporary redirect response to the client using the specified redi=
rect location URL and clears the buffer."
Its just we have been running Tomcat, for 5 years and we have lots of code =
that relied on the fact that sendRedirect did not flush the buffer.
I will drop it, but going to be a while before we can go to 7.0.21.
Jacob
On 09/27/2011 02:32 PM, Jacob Champlin wrote:
Konstantin,
I believe the new flushBuffer() call you added to Response.java
sendRedirect() line #1340. Is breaking all ServletFilters but sending
buy flushing the response before filters have a chance to modify the
response.
Jacob
_________________________________
Kari Scott
Senior Programmer
kari.scott@cdw.com<mailto:kari.scott@cdw.com>
CDW
5520 Research Park Drive
Madison, WI 53711
Office: 608 298 1223
Fax: 608 288 3007
|