DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG· RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://issues.apache.org/bugzilla/show_bug.cgi?id=34769>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND· INSERTED IN THE BUG DATABASE.
http://issues.apache.org/bugzilla/show_bug.cgi?id=34769 Summary: ArrayIndexOutOfBoundsException occurs when reading more than 8192 bytes from the BufferedReader supplied by HttpServletRequest.getReader() Product: Tomcat 5 Version: 5.5.4 Platform: PC OS/Version: Windows XP Status: NEW Severity: normal Priority: P3 Component: Catalina:Modules AssignedTo: tomcat-dev@jakarta.apache.org ReportedBy: [EMAIL PROTECTED] Well...I can supply quite a bit of info, but I can't say you'll have an easy time reproducing the problem. First off, let me provide you with the exception that we experienced. java.lang.ArrayIndexOutOfBoundsException at java.lang.System.arraycopy(Native Method) at org.apache.tomcat.util.buf.CharChunk.append(CharChunk.java:298) at org.apache.tomcat.util.buf.B2CConverter.convert (B2CConverter.java:97) at org.apache.tomcat.util.buf.B2CConverter.convert (B2CConverter.java:76) at org.apache.catalina.connector.InputBuffer.realReadChars (InputBuffer.java:339) at org.apache.tomcat.util.buf.CharChunk.substract(CharChunk.java:384) at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:350) at org.apache.catalina.connector.CoyoteReader.read (CoyoteReader.java:80) at com.spicer.jdl.MatrixXMLSerializable.decodeMime64 (MatrixXMLSerializable.java:142) at com.spicer.jdl.MatrixXMLSerializable.parseMime64 (MatrixXMLSerializable.java:523) at com.spicer.jdl.MatrixXMLSerializable.decodeByteArrayRaw (MatrixXMLSerializable.java:710) at com.spicer.jdl.MatrixXMLSerializable.decodeByteArray (MatrixXMLSerializable.java:641) at com.spicer.jdl.MatrixXMLDispatch.dispatch_ClientWrapperServer (MatrixXMLDispatch.java:109) at com.spicer.jdl.MatrixXMLDispatch.dispatch(MatrixXMLDispatch.java:62) at com.spicer.servlet.MatrixXMLServlet.doPost(Unknown Source) at javax.servlet.http.HttpServlet.service(HttpServlet.java:709) at javax.servlet.http.HttpServlet.service(HttpServlet.java:802) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:237) at org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:157) at org.apache.catalina.core.StandardWrapperValve.invoke (StandardWrapperValve.java:214) at org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java:178) at org.apache.catalina.core.StandardHostValve.invoke (StandardHostValve.java:126) at org.apache.catalina.valves.ErrorReportValve.invoke (ErrorReportValve.java:105) at org.apache.catalina.core.StandardEngineValve.invoke (StandardEngineValve.java:107) at org.apache.catalina.connector.CoyoteAdapter.service (CoyoteAdapter.java:148) at org.apache.coyote.http11.Http11Processor.process (Http11Processor.java:825) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnecti on(Http11Protocol.java:731) at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket (PoolTcpEndpoint.java:526) at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt (LeaderFollowerWorkerThread.java:80) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run (ThreadPool.java:684) at java.lang.Thread.run(Thread.java:595) This exception occurred in Tomcat 5.5.4 whenever we had a larger post to the servlet. We have a java based client-server product that uses a servlet when being deployed for internet use. Essentially, the client converts the calls into an XML stream which it posts to the servlet (called MatrixXMLServlet) that then converts the data back into an RMI call for the server portion of the product. This servlet has been in use, unchanged, for nearly 4 years and hasn't caused an error until now. It works fine with versions of Tomcat before 5.0, but doesn't with 5.5 (I'm not 100% sure about 5.0 so I'll leave it out). Using the FAQ as a guide, I searched for solutions and/or others with the same problem, but was unable to find anything. So, I traced through the Tomcat source code to see if I could understand the problem...and I'm convinced (with little doubt) that there is a Tomcat bug...but I'm not sure what causes the classes to be set up this way. So...I'll describe what I found...maybe it will help. First of all, the doPost() in MatrixXMLServlet does a getReader() on the HttpServletRequest it is passed, and this reader is then set in the MatrixXMLSerializable object. Then, in the decodeMime64() method, we loop reading one character at a time from the BufferedReader (as supplied by getReader()) and process it until we exhaust the stream. But, on larger posts (I think those greater than 8192 characters), we get the exception listed above when trying to read that single character. Now, in this case, the BufferedReader supplied is a CoyoteReader which in turn has an InputBuffer, which in turn has a CharChunk, a ByteChunk, and a B2CConverter. For a read, the CoyoteReader does a read on InputBuffer, which then asks CharChunk for the character. The CharChunk returns the next character that it has in its buffer, but if it has reached the end of what is available it asks InputBuffer for x more characters (where x is the amount of space left in its buffer). Now...here is the problem number 1 ...rather than providing the CharChunk with at most x characters (or resetting the CharChunk if x=0), the InputBuffer asks B2CConverter to transfer everything that ByteChunk has in its buffer (and then refills ByteChunk). So...if there is not enough space left in the CharChunk buffer to add this much data, it tries to accomodate by filling to the limit with what will fit, flushing the buffer and then adding the remainder. But, this leads to the problem we see, because of what the flush actually does (or more precisely "doesn't do"). Essentially, in our case, the start and end pointers are at the same place (which is why CharChunk asks for more data in the first place) and so after filling to the end of the buffer, the flush actually does nothing (except set a flag in the InputBuffer) and then trying to add the rest of the data into the buffer causes it to go past the end of the buffer and generates our exception. That is problem number 2. BUT...if this 2nd insert into the CharChunk buffer doesn't cause the exception we have, then you've lost the data from the 1st insert, because it has been overwritten by the 2nd insert...thus losing data out of the input stream. Okay...this is problem number 3. One possible solution would be to allow the buffer in CharChunk to "wrap" around the end...but then you have to be careful that you don't add more to the start of the buffer than can fit, or you have another case of losing data from the overlap of the 1st insert and the 2nd insert. And...you can't simply reset the start pointer (in CharChunk) upon a flush, because then you'd loose all the data from the 1st insert again...and that's a no-no. I think the whole thing needs to be examined a little more carefully. I suspect that solving problem 1 (and also providing a way to "reset" the CharChunk...perhaps when it requests x=0 more characters) would make the whole thing work as desired. Anyway...we have changed our code in MatrixXMLServlet so that instead of using getReader(), we use getInputStream()...and using HttpServletRequest.getCharacterEncoding(), we wrap the input stream inside an InputStreamReader, and then wrap that inside a BufferedReader. Thus, using this alternative way to read the inputstream eliminates the problem for us. Now...to post this bug, I tried to reproduce the problem with a small, and simple, servlet that simply used the getReader() call and then consumed the input stream one character at a time...and then generating sufficiently large posts to exceed the 8K size. But, the problem didn't occur. So...I don't know what must happen to exactly cause the setup we see inside the CoyoteReader. We have a working solution now, and I can't afford anymore time tracing and debugging Tomcat code...so I hope this is of some help to you. If you have questions, feel free to ask and I'll answer to the best of my knowledge. Thanks. Greg -- Configure bugmail: http://issues.apache.org/bugzilla/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are the assignee for the bug, or are watching the assignee. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]