When I try and retrieve the value of a property of my own custom bean, and my bean throws an exception, the exception message is returned and displayed but the stack history is lost. I can see the code in org.apache.taglibs.standard.lang.jstl.Evaluator, where an ELException is caught and a JspException is thrown, and the rootCause exception is available, and the message is returned, but the stack trace is never passed up the chain. I wasn't sure how to fix this properly, so I patched Evaluator to give me the stack history as follows: /** * * Evaluates the expression at request time **/ public Object evaluate (String pAttributeName, String pAttributeValue, Class pExpectedType, Tag pTag, PageContext pPageContext, Map functions, String defaultPrefix) throws JspException { try { return sEvaluator.evaluate (pAttributeValue, pPageContext, pExpectedType, functions, defaultPrefix); } catch (ELException exc) { StringWriter sw = new StringWriter() ; // SRM PrintWriter pw = new PrintWriter(sw) ; // SRM exc.getRootCause().printStackTrace(pw); // SRM String fullStackTrace = sw.toString() ; // SRM throw new JspException (MessageFormat.format (Constants.ATTRIBUTE_EVALUATION_EXCEPTION, new Object [] { "" + pAttributeName, "" + pAttributeValue, exc.getMessage(), //exc.getRootCause() // SRM fullStackTrace // SRM })); } } There's probably a better way to do it, perhaps? Also, here's a simple webpage fragment that will demonstrate the problem: <%@ page contentType="text/html" %> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %> <%! public class MyBean { public String throwExceptionInHere() { if (true) { throw new RuntimeException("Hey!"); } return ""; } public String getThrowException() { String x = throwExceptionInHere(); return ""; } } %> <% pageContext.setAttribute("myBean", new MyBean()); %> <c:set var="foo" value="${myBean.throwException}" /> <c:out value="${foo}" />
Agree that it is important to expose the original exception thrown by the web application. However, we've opted for a different solution than the one proposed in this bug report. The stack trace does not belong to the textual message of the exception. However, the stack trace information should be made available. The code in Evaluator has therefore been modified so it adds the original exception that occurred as the rootCause of the JspException. This therefore makes the original exception accessible to the container as a Throwable object, not just as text message. Unless the calling code is instrumented to catch exceptions, it then becomes the responsibility of the container to decide what should be displayed. Unfortunately, Tomcat does not currently follow through more than 1 level of nested root exceptions (it only displays a root cause exception defined for ServletException). It would seem desirable for Tomcat to display rootCause exceptions nested at deeper levels. An RFE (see http://nagoya.apache.org/bugzilla/show_bug.cgi?id=15941) has been filed to that effect.