Hi, Thought I'd give a shot at patching a bug (4609) I logged. The basics of the bug is that an IOException is not thrown if out.close() is called from within a JSP page and subsequent calls to write() or println(), etc. are made.
The solution I have affects two classes: org.apache.jasper.runtime.JspWriterImpl org.apache.jasper.compiler.JspParseEventListener The modification to JspWriterImpl was simple: -Added a new boolean instance variable called 'closed' -When JspWriter.close() is called, set 'closed' to true. -Modified the JspWriter.ensureOpen() method. If 'closed' is true, or response is null, throw the IOException. I felt the modification to JspParseEventListener.generateFooter() was necessary as the page code generated: <snip> } catch (Throwable t) { if (out != null && out.getBufferSize() != 0) out.clearBuffer(); if (pageContext != null) pageContext.handlePageException(t); } </snip> So in this case, now that the IOException is thown, we go into the throwable, but the call to out.clearBuffer() generates its own IOException. The problem with this is that the stacktrace becomes inaccurate. Showing the call to clearBuffer() as the top-most call on the stack. So the change I introduced would generate the following code: <snip> if (out != null && out.getBufferSize() != 0) try { out.clearBuffer(); } catch (java.io.IOException ioe) { if (t instanceof java.io.IOException) { if (!(t.getMessage().equals(ioe.getMessage()))) { t = ioe; } } } </snip> So, here if out.clearBuffer() happens to throw an IOException, check to see if the throwable that brought us to this point in the code is an IOException as well. If it is, see if the messages are the same, if they aren't, then there is a new IO issue and set ioe to the throwable which will be handled by pageContext.handlePageException. Otherwise the catch becomes a no-op and pageContext.handlePageException will use the original throwable. Hope that made sense. Anyway, comments are definately welcome. Still getting familiar with the code. Thanks, -rl
Index: JspParseEventListener.java =================================================================== RCS file: /home/cvspublic/jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/compiler/JspParseEventListener.java,v retrieving revision 1.35 diff -u -r1.35 JspParseEventListener.java --- JspParseEventListener.java 2001/11/02 19:36:09 1.35 +++ JspParseEventListener.java 2001/11/20 22:29:40 @@ -378,7 +378,23 @@ writer.pushIndent(); writer.println("if (out != null && out.getBufferSize() != 0)"); writer.pushIndent(); + writer.println( "try {" ); + writer.pushIndent(); writer.println("out.clearBuffer();"); + writer.popIndent(); + writer.println("} catch (java.io.IOException ioe) {"); + writer.pushIndent(); + writer.println("if (t instanceof java.io.IOException) {"); + writer.pushIndent(); + writer.println("if (!(t.getMessage().equals(ioe.getMessage()))) {"); + writer.pushIndent(); + writer.println("t = ioe;"); + writer.popIndent(); + writer.println("}"); + writer.popIndent(); + writer.println("}"); + writer.popIndent(); + writer.println("}"); writer.popIndent(); writer.println("if (pageContext != null) pageContext.handlePageException(t);"); writer.popIndent();
Index: JspWriterImpl.java =================================================================== RCS file: /home/cvspublic/jakarta-tomcat-4.0/jasper/src/share/org/apache/jasper/runtime/JspWriterImpl.java,v retrieving revision 1.1 diff -u -r1.1 JspWriterImpl.java --- JspWriterImpl.java 2000/08/12 00:52:12 1.1 +++ JspWriterImpl.java 2001/11/20 18:10:11 @@ -99,6 +99,7 @@ protected static int defaultCharBufferSize = Constants.DEFAULT_BUFFER_SIZE; protected boolean flushed = false; + protected boolean closed = false; public JspWriterImpl() { super( defaultCharBufferSize, true ); @@ -223,6 +224,7 @@ if (out != null) out.close(); out = null; + closed = true; // cb = null; } } @@ -236,7 +238,7 @@ /** check to make sure that the stream has not been closed */ protected void ensureOpen() throws IOException { - if (response == null) + if ( closed || response == null) throw new IOException("Stream closed"); }
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>