Bug 2500

Summary: FileNotFoundException from service() unintentionally caught
Product: Tomcat 5 Reporter: Shawn Bayern <bayern>
Component: JasperAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: minor    
Priority: P3    
Version: Nightly Build   
Target Milestone: ---   
Hardware: All   
OS: All   

Description Shawn Bayern 2001-07-08 10:08:25 UTC
In the service() method of org.apache.jasper.servlet.JspServlet, I believe the 
scope for which the 'catch FileNotFoundException' block applies is too great;
if a FileNotFoundException is thrown from within the JSP page, the result is
an HTTP 404 error.  The calling code believes the JSP resource itself wasn't
found, when in fact the exception should be treated as internal to the page.
(You can test with

   <% if (1==1) throw new java.io.FileNotFoundException(); %>

I noticed this problem when debugging the code of a colleague, Shawn Douglas,
whose component logic called by the JSP page threw a FileNotFoundException.)

The offending code seems to be:

           try {
                loadIfNecessary(request, response);

                // If a page is to only to be precompiled return.
                if (precompile)
                    return;

                if (theServlet instanceof SingleThreadModel) {
                    // sync on the wrapper so that the freshness
                    // of the page is determined right before servicing
                    synchronized (this) {
                        theServlet.service(request, response);
                    }
                } else {
                    theServlet.service(request, response);
                }

            } catch (FileNotFoundException ex) {

                    ...

but I haven't had the time to look at it thoroughly.  I believe this affects 
Tomcat 3.x as well.  The necessary fix should just be to narrow the scope
of the 'catch' block, but I haven't had a chance to think that through 
completely or test it.  (Sorry! :-) )
Comment 1 Craig McClanahan 2001-07-10 17:48:14 UTC
It seems to me that Jasper is doing the right thing -- if the application wants
to use FileNotFoundException internal to a page, it should swallow that
exception instead of allowing it to propogate back to the container.

Maybe there should be some spec-based description of how exceptions thrown by
JSP page components should be handled?
Comment 2 Craig McClanahan 2001-07-12 18:23:51 UTC
Changing to an "enhancement" request since this is a non-spec issue.
Comment 3 Remy Maucherat 2003-04-15 15:28:44 UTC
At this point, this will not be fixed (if still present in Jasper 2).
Comment 4 Jonathan Leech 2007-03-06 13:27:01 UTC
I disagree with Remy and Craig, and I think if you polled 10 developers, 11 of
them would call this a bug.

The specification pretty clearly lays out what is to happen when a .jsp page
throws an Exception:

public abstract void handlePageException(java.lang.Throwable t)
This method is intended to process an unhandled ’page’ level exception by
forwarding the exception to the specified error page for this JSP. If forwarding
is not possible (for example because the response has already been committed),
an implementation dependent mechanism should be used to invoke
the error page (e.g. “including” the error page instead).
If no error page is defined in the page, the exception should be rethrown so
that the standard servlet error handling takes over.

In this case, if I specifically define an error page for the .jsp, it is
invoked, and the 404 error is not reported - Hurray!

However, contrary to the spec, if an error page isn't defined, the standard
servlet error handling doesn't take over.  For example, defining the following
in web.xml, according to the servlet spec, dictates that the given error page
should be invoked when a FileNotFoundException is thrown:
<error-page>
   <exception-type>java.io.FileNotFoundException</exception-type>
   <location>/error.jsp</location>
</error-page>

As the above doesn't happen, and a 404 error is displayed instead, this behavior
violates the spec and is a bug.  I am reopening it.  As it is still broken in
Tomcat5, I am putting that for the Product field.  As it is not an enhancement
but a bug, I am changing the Severity to 'minor'.
Comment 5 Mark Thomas 2007-08-04 11:19:18 UTC
This is now fixed in svn for 5.5.x and 6.0.x and will be included in the next
releases of each.