Per the advice in this issue: http://issues.apache.org/bugzilla/show_bug.cgi?id=37793 We just tried to apply the following setting to our Tomcat instances -Dorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true A short time after applying this setting, we would start seeing the following stack traces on various random requests. SEVERE: Servlet.service() for servlet jsp threw exception java.lang.ArrayIndexOutOfBoundsException at java.lang.System.arraycopy(System.java) at java.lang.String.getChars(String.java:855) at org.apache.jasper.runtime.BodyContentImpl.write(BodyContentImpl.java:146) at org.apache.jasper.runtime.BodyContentImpl.write(BodyContentImpl.java:159) at org.apache.jsp.tag.web.arch.patterns.DetailInspector.list_tag._jspx_meth_c_005fif_005f3(list_tag.java:683) at org.apache.jsp.tag.web.arch.patterns.DetailInspector.list_tag._jspx_meth_c_005fforEach_005f0(list_tag.java:630) at org.apache.jsp.tag.web.arch.patterns.DetailInspector.list_tag.doTag(list_tag.java:302) at org.apache.jsp.WEB_002dINF.pages.registrar.academic.Student.inspect.pgmstudy_002dtab_jsp._jspx_meth_detail_005flist_005f0(pgmstudy_002dtab_jsp.java:224) at org.apache.jsp.WEB_002dINF.pages.registrar.academic.Student.inspect.pgmstudy_002dtab_jsp.access$0(pgmstudy_002dtab_jsp.java:214) at org.apache.jsp.WEB_002dINF.pages.registrar.academic.Student.inspect.pgmstudy_002dtab_jsp$pgmstudy_002dtab_jspHelper.invoke0(pgmstudy_002dtab_jsp.java:492) at org.apache.jsp.WEB_002dINF.pages.registrar.academic.Student.inspect.pgmstudy_002dtab_jsp$pgmstudy_002dtab_jspHelper.invoke(pgmstudy_002dtab_jsp.java:571) at org.apache.jsp.tag.web.arch.patterns.DetailInspector.inspector_tag.doTag(inspector_tag.java:163) at org.apache.jsp.WEB_002dINF.pages.registrar.academic.Student.inspect.pgmstudy_002dtab_jsp._jspService(pgmstudy_002dtab_jsp.java:151) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98) at javax.servlet.http.HttpServlet.service(HttpServlet.java:803) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:328) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:315) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265) at javax.servlet.http.HttpServlet.service(HttpServlet.java:803) ... If we remove the setting, then things behave normally (albeit with the memory issues discussed in the linked issue). We are running on top of java version 1.6.0.
Upgrading to 5.5.27 may well fix this.
I will try, but nothing in the release notes jumped out at me...
I've upgraded to Tomcat-5.5.27 and Java 1.6.0_11 and I still am getting the exception (with a slightly different stack trace - just not showing the arraycopy) Dec 8, 2008 10:57:20 AM org.apache.catalina.core.StandardWrapperValve invoke SEVERE: Servlet.service() for servlet StripesDispatcher threw exception java.lang.ArrayIndexOutOfBoundsException at java.lang.String.getChars(String.java:855) at org.apache.jasper.runtime.BodyContentImpl.write(BodyContentImpl.java:146) at org.apache.jasper.runtime.BodyContentImpl.write(BodyContentImpl.java:159) at org.apache.jsp.tag.web.labelAndValue_tag._jspx_meth_c_005fif_005f1(labelAndValue_tag.java:1069) at org.apache.jsp.tag.web.labelAndValue_tag._jspx_meth_c_005fif_005f0(labelAndValue_tag.java:1039) at org.apache.jsp.tag.web.labelAndValue_tag.doTag(labelAndValue_tag.java:304) at org.apache.jsp.WEB_002dINF.pages.admissions.prospects.Prospect.inspect.person_002dtab_jsp._jspx_meth_tags_005flabelAndValue_005f0(person_002dtab_jsp.java:608) at org.apache.jsp.WEB_002dINF.pages.admissions.prospects.Prospect.inspect.person_002dtab_jsp._jspService(person_002dtab_jsp.java:199) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
This is caused by bug in implementation of o.a.jasper.runtime.BodyContentImpl#setWriter(Writer) in current tc6.0.x and tc5.5.x code (and thus in TC 6.0.18, TC 5.5.27). That method is called by PageContextImpl#pushBody(Writer) and is the one that prepares the bodycontent instance for reuse. The current code, with comments omitted, is the following: 558: void setWriter(Writer writer) { 559: this.writer = writer; 560: closed = false; 561: if (writer != null) { 571: if (bufferSize != 0) { 572: bufferSizeSave = bufferSize; 573: bufferSize = 0; 574: } 575: } else { 576: bufferSize = bufferSizeSave; 577: clearBody(); 578: } 579: } The unconditional assignment on line 576 is wrong. Consider the following sequence of events: 1. setWriter(null) bufferSize = bufferSizeSave is assigned 0 // <- this is wrong (1) 2. write more than 512 bytes of data bufferSize becomes > 512 3. setWriter(writer) bufferSizeSave = bufferSize is assigned value that is > 512 4. setWriter(null) bufferSize = bufferSizeSave is > 512 BodyContentImpl#clear() is called and shrinks the buffer to its default size of 512, bufferSize becomes 512 5. write several bytes of data 6. setWriter(null) bufferSize = bufferSizeSave is > 512 // <- this is wrong (2) 7. write more than 512 bytes of data At this point the ArrayIndexOutOfBoundsException should occur, because bufferSize is > 512, but the buffer is only 512 bytes.
Created attachment 23076 [details] webapp that reproduces the issue To reproduce the issue: 1. deploy the war file 2. append the following line to conf/catalina.properties : org.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true 3. launch the server and access http://localhost:8080/bug46354/ 4. Error 500 report is observed with stacktrace of java.lang.ArrayIndexOutOfBoundsException exception Without step 2. the page works and displays some text. Reproducible in TC 5.5.27 and in current tc6.0.x
Created attachment 23077 [details] patch for BodyContentImpl class of tc6.0.x I think that the straightforward way to fix this is to remove the private bufferSizeSave field and the trick from the #setWriter() method and to overwrite the #getBufferSize() method. The bufferSize field is just declared in JspWriter and is not used for calculations neither there nor in BodyContent class, nor the JSP 2.1 spec requires any calculations from them (all methods except the #getBufferSize() getter are abstract). All the calculations are implemented in BodyContentImpl. Thus the attached patch. It fixes the issue.
Many thanks for the test case and patch, as well as your efforts in tracking this one down. The patch has been applied to trunk and proposed for 6.0.x and 5.5.x
This has been fixed in 6.0.x and will be included in 6.0.20 onwards. Thanks again for the patch.
This has been fixed in 5.5.x and will be included in 5.5.28 onwards