You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by "Tuomas Kiviaho (JIRA)" <de...@myfaces.apache.org> on 2006/05/19 10:16:30 UTC

[jira] Commented: (MYFACES-650) (Patch provided) Multiple Portlets Navigationproblem

    [ http://issues.apache.org/jira/browse/MYFACES-650?page=comments#action_12412501 ] 

Tuomas Kiviaho commented on MYFACES-650:
----------------------------------------

I've been struggling with the case as well and some I've some questions & thoughts my self that I'd like to present here.

Is there a need other than current MyFacesGenericPortlet (plus maybe some more internal dependencies in myfaces-impl) to keep the same faces context between processAction and render? After "resetting" facescontext it's state consists only of external context ( that is replaced anyway) dependencies, the viewroot plus messages. The latter ones could be carried over from processAction to render in similar manner as now is done to the faces context itself as whole. This is how Sun's jsf-portlet implementation does it, but I see it overall to be more of a technology spike than a robust solution, so they may be skipping some potential permutations that may render the approach as nonworking solution.

How should the request for client side state saving in this case be treated? Shouldn't there be an effort to use ActionResponse#setRenderParameter instead of session attributes. ActionResponse#sendRedirect has restrictions, but since we'd be skipping the render phase anyhow I don't see a a problem here. This naturally makes state parameters "reusable" if/when Portlet#render is reached via Response#sendRedirect. Bookmarking isn't going to be beautiful, but by "reusable" I mean that (for example) ticketing is needed to rule out any misuse.
Related link: <http://sfjsf.blogspot.com/2006/03/how-were-going-to-fix-jsf-state-saving.html>

> (Patch provided) Multiple Portlets Navigationproblem
> ----------------------------------------------------
>
>          Key: MYFACES-650
>          URL: http://issues.apache.org/jira/browse/MYFACES-650
>      Project: MyFaces Core
>         Type: Bug

>   Components: Portlet_Support
>     Versions: 1.1.2-SNAPSHOT
>  Environment: myfaces-api + myfaces-impl (rev. 292564) , pluto-1.0.1-rc4 (binary bundle), jdk1.5.0_03-b07
>     Reporter: Tanju Erinmez
>     Assignee: Stan Silvert
>  Attachments: myfaces-impl-src.diff, navdemo.war
>
> First of all, congratulations to the TCK pass! Myfaces is a terrific product! Especially the combination with portlets is a joy to work with!
> However, I have come across a tiny little problem [1] which might be even easier to fix [2,3] :-) I'm going to attach a patch as well as a demo war in order to reproduce the issue if upload threshold permits.
> It would be great if these patches could be included.
> TIA,
> Tanju
> PS: This issue is not related to 549. I have analyzed that one as well and will post a desc shortly.
> [1] Scenario
> ------------------
> The problem specifically arises when two (or more) portlets from the same war deployable are positioned on the same page AND the state saving mode is set to client. Well, the workaround would be to set it to server, however, the client mode actually reveals the underlying issue.
> Consider the following scenario:
> 6 jsp pages: view1.jsp... view6.jsp with one commandButton each
> PortletA starts with view1 and iterates upon a buttonclick  to view2, view3 and back to view1 etc.
> PortletB starts with view4 and moves on to view5, view6 and back to view4 etc
> On startup, situation is: 1, 4
> 1. After action in A ->  2, 4
> 2. After action in B ->  2, 5
> 3. After action in A ->  2, 5    <- Wrong! should be 3, 5
> 4. After action in A -> 3, 5    <- Another action is needed to move to 3, 5
> This behavior (inversed) also appears if the sequence is started with portlet B instead of A.
> [2] Possible explanation
> ------------------------------------
> The actual problem is that a facesContext, which is kept in the PortletSession, also drags a  responseWriter along. However, this writer becomes stale as soon as the processing of the respective view (underlying jsp) is concluded.
> When this facesContext is retrieved by a subsequent RenderRequest the UIComponentTag class will not create a new responseWriter, instead it will use the one from the facesContext. (see UIComponentTag.java, setupResponseWriter())
> Fastforward: The ViewTag instance (doAfterBody()) is not able to replace the form state marker because the actual content has been written out to the bodyContent of the last page and not the view-to-be. The consequence is that the marker is written out as is.
> Now as soon as action 3. is invoked, the resoreView phase is not able to restore the tree. It just skips the other phases and goes straight for the render phase which renders the current view again.
> This problem does not occur in the non-portlet use-case because a new facesContext (with a noninitialized responseWriter) is created upon every request.
> [3] Resolution
> ----------------------
> A simple solution would be to just nullify all non-essential instance variables of facesContext (specifically the _responseWriter variable) after the facesContext is retrieved in facesRender() of MyFacesGenericPortlet.
> A more symmetric solution would be to reset the responseWriter where it is actually assigned namely in UIComponentTag but this does not seem to be possible due to the API which does not permit a null value assignment. This actually makes perfectly sense given its intention as throwaway object in a well defined a lifecycle.
> I have tested this fix on pluto, and it seems to work like a charm.

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