We should never - ever - just swallow a RuntimeException coming out of
a listener call. It should _always_ be passed to the exception
handler.
We agreed on this on the way to JSF 2.0.
best regards,
Martin
On 7/1/11, Leonardo Uribe <lu4242_at_gmail.com> wrote:
> Hi
>
> Checking JSF 2.0 ExceptionHandler API, an user in MyFaces notice there
> is an inconsistency about how AbortProcessingException is handled
> (MYFACES-3199).
>
> Let's suppose this example:
>
> <h:inputText valueChangeListener="#{bean.processValueChange}">
>
> The spec javadoc of
> javax.faces.event.MethodExpressionValueChangeListener.processValueChange
> (on method detail) says this:
>
> "... Call through to the MethodExpression passed in our constructor.
> First, try to invoke the MethodExpression passed to the constructor of
> this instance, passing the argument ValueChangeEvent as the argument.
> If a MethodNotFoundException is thrown, call to the zero argument
> MethodExpression derived from the MethodExpression passed to the
> constructor of this instance. If that fails for any reason, throw an
> AbortProcessingException, including the cause of the failure. ..."
>
> Look the last line that says "... If that fails for any reason, throw
> an AbortProcessingException, including the cause of the failure ...".
> Now suppose a RuntimeException is thrown inside the listener. The spec
> clearly says that any exception should be wrapped into an
> AbortProcessingException, and the final effect is that exception is
> just logged and the page is rendered, so from the client side you
> don't see any error.
>
> The problematic code is this one:
>
> <h:inputText >
> <f:valueChangeListener binding="#{bean}" />
> </h:inputText>
>
> In this case, if a RuntimeException or any other happens inside the
> listener, instead catch it and rethrow it as an
> AbortProcessingException, the exception "comes out", the error page is
> shown. This is the stack trace in Mojarra:
>
> java.lang.RuntimeException: process validation throwValueChange failed!
> at
> org.apache.myfaces.testex.UserBean2.processValueChange(UserBean2.java:57)
> at
> com.sun.faces.facelets.tag.jsf.core.ValueChangeListenerHandler$LazyValueChangeListener.processValueChange(ValueChangeListenerHandler.java:128)
> at
> javax.faces.event.ValueChangeEvent.processListener(ValueChangeEvent.java:134)
> at
> javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:777)
> at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:752)
> at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1167)
> at
> com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76)
> at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
> at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
> at javax.faces.webapp.FacesServlet.service(FacesServlet.java:508)
>
> Since both MyFaces and Mojarra shares the same code from facelets, the
> effect is present in both implementations.
>
> I think the problem can be found too on f:actionListener and other
> similar tags.
>
> It is clear the wrapping should be done and the error just need to be
> logged, but before apply any fix on 2.0.x or 2.1.x branch I think it
> is better to ask if that is true. Anyway, a clarification must be
> included on the spec for JSF 2.2, because it could be components in
> JSF libraries that requires do this fix too.
>
> Suggestions are welcome.
>
> Leonardo Uribe
>
--
http://www.irian.at
Your JSF powerhouse -
JSF Consulting, Development and
Courses in English and German
Professional Support for Apache MyFaces