I'm using JBoss/Tomcat bundle JBoss version 3.2.7 running on XP SP2
I've been studying and experimenting all day with the various ways of implementing JSP error pages. It appears that there are 2 ways:
1) map HTTP error codes or Java Exception classes to error pages via web.xml deployment descriptors
2) use page directives in JSPs to declare one JSP to be the error page and to declare which error page a given JSP should defer to when an error occurs
Error code to error page mapping
From reading everything I could possibly find, I've determined that a JSP error page earns the status of being an actual error page if it has a page directive that looks like this:
<%@page isErrorPage="true" %>
When a JSP is an error page, it has an implicit object called "exception". There is a trick, however, as under certain circumstances this object is null. The most common circumstance under which this object is null is when the error page is mapped to HTTP error 404. The object is present but it is null so you can't use either of the following scriptlet expressions that you'd probably want to use:
<%= exception.getClass().getName() %>
<%= exception.getMessage() %>
When you try to use these in your 404 error page, you get null pointer exceptions and get error 500 instead which is pretty annoying since you are probably doing a really simple test like entering a URL that you know won't work. You can save yourself lots of trouble if you don't try to get anything out of the implicit exception object for a 404 error page.
For other HTTP error codes the exception object is non-null which is very nice. By mapping HTTP error code 500 to a single error JSP, you can catch most runtime errors that would otherwise produce an ugly stack trace with likely cause page. The mapping web.xml would look like this:
(I've included the <welcome-file-list> node for context.)
<welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <error-page> <error-code>404</error-code> <location>/WEB-INF/errorpages/html404.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/WEB-INF/errorpages/html500.jsp</location> </error-page>
By having a nice-looking html500.jsp ( I should have named it http500.jsp) file with the same look, feel, and navigation bar as the rest of the web app, I can display system and application errors nicely.
Page directives for error pages
The other approach is to declare via page directives on individual JSPs which error JSP should load when the source JSP encounters an error.
I have a JSP that gathers user data and submits to another JSP which connects to an EJB to put that data into an RDBMS. If any of the data is out of range of what makes sense for the business rules of the EJBs, they throw custom, checked exceptions. The submitting JSP catches those checked exceptions, wraps them with RuntimeException and rethrows them. The plan is to have the web container become aware of a RuntimeException and trigger the error page for the submitting JSP. The error page has the same fields as the first JSP into which the user enters data but it also has a place at the top of the page to display the message portion of whichever exception the EJB threw.
(It's pretty slick because the user gets to see the error message and still has all of the data previously entered in all of the fields. I'm very happy with the way that this web app is working and am very pleased I was able to propagate a checked exception from an EJB all the way into the web container in such a manner that the web container triggered the submit JSP's error page. This task took a while to figure out.)
Here's the problem
Looking back at the top of this posting you can see there are methods 1 and 2 for implementing JSP error pages. If I use only one method or the other, there are no problems. If, however, I map HTTP error code 500 to my generic error page AND I use page directives to point my submitting JSP's errors to my error JSP (the one with the error message at the top and the input fields in HTML with their values preserved), I don't get my nice, fancy error JSP. Instead, I get the error page mapped to error 500 AND the implicit exception object is null.
Maybe I shouldn't have wrapped and thrown the checked exception from the EJB with RuntimeException. I only did it because it was the only thing I could think of that worked. And, it worked fine until I introduced the mapping of error 500.
Any ideas on where I may have gone wrong? or what I can or should do so that I can use both methods 1 and 2 without them interfering with each other?