Topic: Servlets and JSP, Declarative Exception Handling
I created the following error declaration in my web.xml
<error-page>
<exception-type>exercises.MyException</exception-type>
<location>/WEB-INF/errors/error.jsp</location>
</error-page>
Then I created MyException class
public class MyException extends Exception {
public static int JustThrowError(int n) throws MyException{
if(n<10)
throw new MyException();
else
return n;
}
}
To test this, I used a simple jsp.
<body>
<%@ page import="exercises.*" %>
<%=MyException.JustThrowError(9) %>
</body>
I expected that it shows an error page(error.jsp) designated in my web.xml. Instead i am getting exception stack trace as shown below.
Could anyone explain why the exception is not caught and redirected to error.jsp as defined in my web.xml?
SEVERE: Servlet.service() for servlet [jsp] in context with path [/my-struts-errors] threw exception [An exception occurred processing JSP page /forms/riskyPage.jsp at line 9
6: </head>
7: <body>
8: <%@ page import="exercises.*" %>
9: <%=MyException.JustThrowError(9) %>
10: </body>
11: </html>
Stacktrace:] with root cause
exercises.MyException
at exercises.MyException.JustThrowError(MyException.java:8)
at org.apache.jsp.forms.riskyPage_jsp._jspService(riskyPage_jsp.java:63)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:417)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:391)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:306)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:541)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:383)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:288)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
I am guessing that your problem is that Tomcat is wrapping your exception in a org.apache.jasper.JasperException (in JspServletWrapper.handleJspException). To test this, try changing to this:
I bet that works, as will putting superclasses such as java.lang.Throwable. (This isn’t a solution to your specific problem though, obviously).
You can get at the exception in error.jsp so I guess you could put your exception-type-dependent logic in there.
However, as a general point – using scriptlets is a bad practice (see jsp for business layer for some of the reasons why). I think that you throw an exception from a tag or servlet (or other ‘middle tier’ code) it won’t be wrapped in JasperException and so will work as you expect. (I’ll investigate this at some point and then edit my answer – unless someone else confirms either way in a comment).