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! :-) )
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?
Changing to an "enhancement" request since this is a non-spec issue.
At this point, this will not be fixed (if still present in Jasper 2).
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'.
This is now fixed in svn for 5.5.x and 6.0.x and will be included in the next releases of each.