Bug 31171 - ClassCastException in org.apache.jasper.runtime.PageContextImpl.getException
Summary: ClassCastException in org.apache.jasper.runtime.PageContextImpl.getException
Alias: None
Product: Tomcat 5
Classification: Unclassified
Component: Jasper (show other bugs)
Version: 5.0.19
Hardware: All other
: P3 normal (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
Depends on:
Reported: 2004-09-10 16:53 UTC by Steve Revilak
Modified: 2004-11-16 19:05 UTC (History)
0 users


Note You need to log in before you can comment on or make changes to this bug.
Description Steve Revilak 2004-09-10 16:53:50 UTC
I am writing to report a case where calling PageContextImpl.getException()
can result in a ClassCastException.  This occurred in tomcat 5.0.19,
but examination of tomcat 5.0.28's source code, the problem could
occur there as well.

In my application, I have an jsp declared as an error page.  This
error page uses a tag to record some additional information.  The
first few lines of this tag are as follows:

    public void doTag() throws IOException, JspException
	try {

	    PageContext context = (PageContext)getJspContext();
	    JspWriter out = context.getOut();
            HttpServletRequest request = (HttpServletRequest) context.getRequest();
            Throwable error = context.getException();
            // proceed to log the exception and some of the
            // surrounding contextual information

In one case, the `catch' associated with this try caught a
ClassCastException from PageContextImpl.getException():

  // line 608 in 5.0.19's PageContextImpl.java
  // line 560 in 5.0.28's PageContextImpl.java
  public Exception getException() { return (Exception)request.getAttribute(EXCEPTION); }

This would occur if the error was a result of a java.lang.Throwable.

What possible paths might lead up to this?

The _jspService() generated by JspC typically terminates with
something like the following:

    } catch (Throwable t) {
      if (!(t instanceof SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
        if (pageContext != null) pageContext.handlePageException(t);
    } finally {
      if (_jspxFactory != null) _jspxFactory.releasePageContext(pageContext);

It's catching a Throwable.

PageContextImpl.handlePageException() (lines 730 - 745 in version
5.0.28) does this: 

   public void handlePageException(final Throwable t)
        throws IOException, ServletException
        if (t == null)
            throw new NullPointerException("null Throwable");

        if (System.getSecurityManager() != null){
                AccessController.doPrivileged(new PrivilegedExceptionAction(){
                    public Object run() throws Exception{
                        return null;

It's dealing with throwables.

Continuing on to doHandlePageException(), (lines 763 - 786 in version

    private void doHandlePageException(Throwable t)
        throws IOException, ServletException {

        if (errorPageURL != null && !errorPageURL.equals("")) {

             * Set request attributes.
             * Do not set the javax.servlet.error.exception attribute here
             * (instead, set in the generated servlet code for the error page)
             * in order to prevent the ErrorReportValve, which is invoked as
             * part of forwarding the request to the error page, from
             * throwing it if the response has not been committed (the response
             * will have been committed if the error page is a JSP page).
            request.setAttribute("javax.servlet.jsp.jspException", t);
                new Integer(HttpServletResponse.SC_INTERNAL_SERVER_ERROR));
            ((HttpServletRequest) request).getRequestURI());
                try {

It's also dealing with Throwables.

The following two (short) jsp files reproduce the problem consistently.

--------------- Page: foo.jsp -----------------------------------
<%@ page session="false"

<html><body>hello world</body></html>
  if (1 + 1 == 2) {
    throw new Throwable("The cake fell in the mud");

------------------- Page: myerror.jsp ----------------------------
<!-- myerror.jsp -->
<%@ page session="false"

An error occurred:



Perhaps getException() could take extra steps to ensure that the
object being returned is indeed an exception (and wrap it if it's
Comment 1 Yoav Shapira 2004-09-15 18:14:29 UTC
Good, interesting catch.  It seems like something simple in the PageContext 
imlpementation, like

if(! (exception instanceof Exception)) {
  exception = new JspException(exception);

would be a good wrap.  It only wraps if needed, and the JspException 
constructor takes a Throwable root cause, so I think we'll be all set.  I'll 
wait to see what more experienced Jasper developers (Kin-Man?) think of this.
Comment 2 Steve Revilak 2004-09-19 02:04:05 UTC
Yoav Shapira's suggestion (2004-09-15 18:14) seems like a reasonable way to handle this.  If my 
opinion matters :)
Comment 3 Yoav Shapira 2004-09-20 18:09:33 UTC
Fixed for 5.0.29 and 5.5.3.