You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@struts.apache.org by "Craig McClanahan (JIRA)" <ji...@apache.org> on 2006/06/21 02:46:16 UTC

[jira] Created: (WW-1357) JSF lifecycle implementation does not conform to JSF specification requirements

JSF lifecycle implementation does not conform to JSF specification requirements
-------------------------------------------------------------------------------

         Key: WW-1357
         URL: http://issues.apache.org/struts/browse/WW-1357
     Project: Struts Action 2
        Type: Bug

  Components: Interceptors  
    Reporter: Craig McClanahan


Section 11.1 of the JSF specification describes the required processing for each phase of the request processing lifecycle.  The following three bullets, quoted from the spec, describe the requirements related to calling phase listeners.

* Call the beforePhase() method of each relevant listener, in the order
  that the listeners were registered.

* If no called listener called the FacesContext.renderResponse() or
  FacesContext.responseComplete() method, execute the functionality
  required for the current phase.

* Call the afterPhase() method of each relevant listener, in the reverse
  of the order that the listeners were registered.

In other words, if the beforePhase() method on a phase listener is called, then the afterPhase() listener must also be called -- whether or not the functionality specific to this phase is actually executed.  This requirement is violated by the current jsf stack of interceptors, which often call informPhaseListenersBefore() and then return if certain conditions are met, without calling informPhaseListenersAfter().  The original MyFaces code from which these implementations appear to be cut-n-pasted enforced the requirement by using a try/catch/finally block.  Something similar should be done here.

An example of this problem is the following code from org.apache.struts.action2.jsf.FacesResult in the render() method:

    informPhaseListenersBefore(facesContext, PhaseId.RENDER_RESPONSE);
    if (isResponseComplete(facesContext, "render", true)) {
        return;
    }
    ... perform the rendering logic, possibly throwing an exception ...
    informPhaseListenersAfter(facesContext, PhaseId.RENDER_RESPONSE);

In other words, the call to the afterPhase listener will be skipped if responseComplete is called (by a beforePhase event listener), or if the rendering code throws an exception.


-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/struts/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Resolved: (WW-1357) JSF lifecycle implementation does not conform to JSF specification requirements

Posted by "Don Brown (JIRA)" <ji...@apache.org>.
     [ http://issues.apache.org/struts/browse/WW-1357?page=all ]
     
Don Brown resolved WW-1357:
---------------------------

    Fix Version: 2.0.0
     Resolution: Fixed
      Assign To: Don Brown

Good catch, Craig. Fixed.  This reminds me - to accomdate pure JSF apps that are using JSF navigation, I think it should be possible to make a higher level interceptor/result set that uses the defined Lifecycle class and NavigationHandler.  This would be desirable when you want to use Action 2 just for AJAX or a few simple stateless pages, with the rest using the normal JSF capabilities.  I'll open up a new ticket on it.

> JSF lifecycle implementation does not conform to JSF specification requirements
> -------------------------------------------------------------------------------
>
>          Key: WW-1357
>          URL: http://issues.apache.org/struts/browse/WW-1357
>      Project: Struts Action 2
>         Type: Bug

>   Components: Interceptors
>     Reporter: Craig McClanahan
>     Assignee: Don Brown
>      Fix For: 2.0.0

>
> Section 11.1 of the JSF specification describes the required processing for each phase of the request processing lifecycle.  The following three bullets, quoted from the spec, describe the requirements related to calling phase listeners.
> * Call the beforePhase() method of each relevant listener, in the order
>   that the listeners were registered.
> * If no called listener called the FacesContext.renderResponse() or
>   FacesContext.responseComplete() method, execute the functionality
>   required for the current phase.
> * Call the afterPhase() method of each relevant listener, in the reverse
>   of the order that the listeners were registered.
> In other words, if the beforePhase() method on a phase listener is called, then the afterPhase() listener must also be called -- whether or not the functionality specific to this phase is actually executed.  This requirement is violated by the current jsf stack of interceptors, which often call informPhaseListenersBefore() and then return if certain conditions are met, without calling informPhaseListenersAfter().  The original MyFaces code from which these implementations appear to be cut-n-pasted enforced the requirement by using a try/catch/finally block.  Something similar should be done here.
> An example of this problem is the following code from org.apache.struts.action2.jsf.FacesResult in the render() method:
>     informPhaseListenersBefore(facesContext, PhaseId.RENDER_RESPONSE);
>     if (isResponseComplete(facesContext, "render", true)) {
>         return;
>     }
>     ... perform the rendering logic, possibly throwing an exception ...
>     informPhaseListenersAfter(facesContext, PhaseId.RENDER_RESPONSE);
> In other words, the call to the afterPhase listener will be skipped if responseComplete is called (by a beforePhase event listener), or if the rendering code throws an exception.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/struts/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira