ELException catched in lifecycle phase RENDER_RESPONSE about: the raised exception does
not have a readable property
--------------------------------------------------------------------------------------------------------------------
Key: JBSEAM-3354
URL:
https://jira.jboss.org/jira/browse/JBSEAM-3354
Project: Seam
Issue Type: Bug
Components: EL
Affects Versions: 2.0.0.GA
Environment: Jboss 4.2.1.GA, JDK 1.5.0_11
Reporter: Julien Kronegg
When an Exception with a specific getter pattern is raised in the ".page.xml"
page, the Seam debug page is not displayed, but instead gives a 404 error and the log
contains the follow trace:
22:17:09,328 WARN [lifecycle] phase(RENDER_RESPONSE
6,com.sun.faces.context.FacesContextImpl@2f1e34) threw exception: javax.el.ELException:
/file:/C:/Workspace/jboss-4.2.1.GA/server/default/deploy/networking20.ear/networking20.war/WEB-INF/lib/jboss-seam-debug.jar!/META-INF/debug.xhtml:
The class 'org.hibernate.exception.NestableRuntimeException' does not have a
readable property 'message'.
/file:/C:/Workspace/jboss-4.2.1.GA/server/default/deploy/networking20.ear/networking20.war/WEB-INF/lib/jboss-seam-debug.jar!/META-INF/debug.xhtml:
The class 'org.hibernate.exception.NestableRuntimeException' does not have a
readable property 'message'.
com.sun.facelets.compiler.TextInstruction.write(TextInstruction.java:48)
com.sun.facelets.compiler.UIInstructions.encodeBegin(UIInstructions.java:39)
com.sun.facelets.compiler.UILeaf.encodeAll(UILeaf.java:149)
com.sun.facelets.component.RepeatRenderer.encodeChildren(RepeatRenderer.java:50)
com.sun.facelets.component.UIRepeat.process(UIRepeat.java:357)
com.sun.facelets.component.UIRepeat.encodeChildren(UIRepeat.java:617)
com.sun.facelets.tag.jsf.ComponentSupport.encodeRecursive(ComponentSupport.java:244)
com.sun.facelets.tag.jsf.ComponentSupport.encodeRecursive(ComponentSupport.java:249)
com.sun.facelets.tag.jsf.ComponentSupport.encodeRecursive(ComponentSupport.java:249)
org.jboss.seam.debug.jsf.SeamDebugPhaseListener.beforePhase(SeamDebugPhaseListener.java:51)
com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:222)
com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:144)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:245)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
org.jboss.seam.debug.hot.HotDeployFilter.doFilter(HotDeployFilter.java:68)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:73)
org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:85)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:44)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:154)
org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:260)
org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:366)
org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:493)
org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:60)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58)
org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:241)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:580)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
java.lang.Thread.run(Thread.java:595)
This can be reproduced with the following test case:
------------------------------------------------ class A
--------------------------------------
import javax.ejb.Local;
@Local
public interface A {
public String getMessage();
public String getMessage(int num);
public String getMessage2();
public String getMessage3();
public void destroy();
}
-------------------------------------------------------------------------------------------------
--------------------------------- class AAction (extends A) ----------------------------
import javax.ejb.Remove;
import javax.ejb.Stateful;
import org.hibernate.exception.NestableRuntimeException;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.Name;
@Stateful
@Name("a")
public class AAction implements A {
public String getMessage1() { return "foobar"; }
public String getMessage1(int i) { return ""+i; }
public String getMessage2() { throw new NestableRuntimeException("xxx"); }
public String getMessage3() { throw new IndexOutOfBoundsException("xxx"); }
@Destroy
@Remove
public void destroy() {}
}
--------------------------------------------------------------------------------------------
--------------------------------------- a.xhtml
------------------------------------------
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets">
</ui:composition>
-------------------------------------------------------------------------------------------
---------------------------------------a.page.xml -------------------------------------
<page>
<action execute="#{a.getMessage2}"/>
</page>
--------------------------------------------------------------------------------------------
Depending on the "execute" field in the "a.page.xml" page, the result
is not the same:
- "#{a.getMessage1}" => the A.getMessage1() method is executed normally
- "#{a.getMessage2}" => the stacktrace above is displayed in the log files
and the page is breaked (error 404?)
- "#{a.getMessage3}" => the Seam debug page is displayed with a description
of the exception (here, an IndexOutOfBoundsException was chosen)
The excepted behavior would be that all exceptions lead to displaying the Seam debug
page.
The short story about why the "a.getMessage2" test case displays the stacktrace
is the following: to generate the Seam debug page, exception message must be obtained. The
raised exception (NestableRuntimeException) has a getter getMessage() and another
getMessage(int), and javax.el.BeanELResolver (used to execute the EL) which uses
java.beans.Introspector (the builder used to compute the list of properties) cannot
recognize the getMessage() getter because the Introspector merges getMessage() and
getMessage(int) into getMessage(int). Consequently, the exception appears to have no
getMessage() method (from the BeanELResolver viewpoint), which causes the Seam debug page
to break.
The long story is here:
http://seamframework.org/Community/AnybodyHitThisBugInSeam#comment35710
IMHO, this is a problem in the javax.el.BeanELResolver (from el-api.jar), which uses the
very generic and complicated java.beans.Introspector class for a very simple use of
obtaining the getters and setters.
I know that its a JDK/javax.el issue, but Pete Muir suggested me to file a JIRA issue, so
there it is. The difficulty behind that issue is that the BeanELResolver and Introspector
are used for multiple purposes and that correcting them could imply large side effects, so
it is probably why the issue has not yet been corrected in the BeanELResolver.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira