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]>

Reply via email to