[ http://issues.apache.org/struts/browse/SHALE-30?page=all ]

Craig McClanahan moved STR-2703 to SHALE-30:
--------------------------------------------

      Project: Shale  (was: Struts Action 1)
          Key: SHALE-30  (was: STR-2703)
    Component:     (was: Shale)
      Version:     (was: Unknown)
    Assign To:     (was: Struts Developer Mailing List)

> ShalePhaseListener executes ViewController.prerender twice after exception
> --------------------------------------------------------------------------
>
>          Key: SHALE-30
>          URL: http://issues.apache.org/struts/browse/SHALE-30
>      Project: Shale
>         Type: Bug

>  Environment: Operating System: other
> Platform: Other
>     Reporter: Darren Boyd
>  Attachments: patchfile.txt, view.patch
>
> In some situations when an exception is thrown from the prerender() call of a
> ViewController the call will be made twice in the same request.  I've come
> across this when the application container is configured to forward to a JSF
> page when encountering an error.
> In my situation, I have configured Tomcat (in web.xml) to forward to an error
> page for any '500' error.  When a ViewController throws an exception from
> prerender() the exception finds its way to the container which then forwards 
> to
> the error page.  Since the error page is a JSF page, the JSF lifecycle is
> processed for this new 'view'.  There is no ViewController mapped to the error
> page.  However, due to the exception previously, the 
> ViewController.prerender()
> that was previously called gets called again.  
> After looking at the code I found a simple reason as to why this is happening.
> The ShalePhaseListener.beforeRenderResponse(PhaseEvent) method is responsible
> for calling the prerender().  This is what it looks like...
>     private void beforeRenderResponse(PhaseEvent event) {
>         Map map = 
> event.getFacesContext().getExternalContext().getRequestMap();
>         ViewController vc = (ViewController)
>           map.get(ShaleConstants.VIEW_RENDERED);
>         if (vc == null) {
>             return;
>         }
>         vc.prerender();
>         map.remove(ShaleConstants.VIEW_RENDERED);
>     }
> Since the exception is being thrown from the vc.prerender() call, the
> ViewController is never removed from the faces request map.  Therefore, after
> the forward happens and the PhaseListener gets called again, there's still a
> ViewController in the request which gets called again.
> I checked out the source from the repository and made a very small change to 
> fix
> this.  I basically removed the ViewController from the map before calling
> prerender().  This may not be the best way to deal with this issue, but I 
> think
> it does better represent the intention of the code (especially given the
> 'contract' of ViewController).
> To reproduce this, add something like the following to your web.xml file...
> <error-page>
>     <error-code>500</error-code>
>     <location>/error.jsf</location>
> </error-page>
> Add to this whatever configuration is required to get error.jsf to work as a 
> JSF
> page.  Make sure there is no shale ViewController mapped to /error.jsf.
> On a different page (make sure it is a different JSF ViewID) add a
> ViewController, appropriately mapped in Shale and throw an exception from
> prerender().

-- 
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


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to