[ 
https://issues.apache.org/jira/browse/MYFACES-3119?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13027149#comment-13027149
 ] 

Leonardo Uribe commented on MYFACES-3119:
-----------------------------------------

Thanks Matt for the demo, it helps a lot to understand what's going on.

Surprisingly the code on MyFaces is correct. The problem is not something 
related to the implementation. So why Mojarra can do it and MyFaces cannot?

In JSF 2.0, Partial State Saving (PSS) was introduced based on this hypothesis 
(extracted from "What's New in JSF 2.0" article by Andy Schwartz):

"... JSF 2.0 addresses these issues with the introduction of a new “partial” 
state saving mechanism. This solution was inspired by a proposal that Adam 
Winer made (and implemented in Apache Trinidad) over 3 years ago. The key 
concept is that saving the entire state of the component tree is redundant, 
since the component tree can always be restored to its initial state by 
re-executing the view (ie. by re-executing Facelet handlers to re-create the 
component tree).

If we use the view definition to restore the component tree to its initial 
state, then the only state that needs to be saved is state that has been 
modified since the view was initially created. And since in most cases the 
number of components that are modified after component tree creation is small, 
the size of this delta state is typically much smaller than the full component 
tree state. ..."

If you execute some code that affects the state of a component before 
markInitialState() methods and don't do the same when the view is built on 
restore view phase, exceptions like the one described here will happen. 

The example here tries to add a listener before render response phase, but note 
in render response phase happens these important steps:

1. vdl.buildView
2. publish PreRenderViewEvent
3. viewHandler.renderView

On the first one, all view is marked, calling markInitialState. In few words, 
this means that all subsequent changes will be considered "delta" data and 
should be saved on the state. The difference between MyFaces and Mojarra is 
that Mojarra does not call markInitialState over UIViewRoot instance, but 
MyFaces does. I notice it doing some tests for PSS long time ago. Note to get 
the minimal possible state, it is adviced to call markInitialState over 
UIViewRoot, like MyFaces does.

So what are the possible solutions to this issue:

1. Create a custom class extending from ViewHandlerWrapper that do this:

    public void renderView(FacesContext context, UIViewRoot viewToRender)
            throws IOException, FacesException
    {
        viewToRender.clearInitialState();
        super.renderView(context, viewToRender);
    }

  This is my preferred option, because it will work with both JSF 
implementations and is easy to do.

2. Use PreRenderViewEvent instead a PhaseListener.

3. Add the code on the custom ViewHandlerWrapper renderView method before call 
the delegate one.

I'll close this issue as not a problem. Interesting issue.

> NullPointerException in 
> UIComponentBase.restoreDeltaSystemEventListenerClassMap() when UIViewRoot 
> subscribed to PostAddToViewEvent
> ----------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: MYFACES-3119
>                 URL: https://issues.apache.org/jira/browse/MYFACES-3119
>             Project: MyFaces Core
>          Issue Type: Bug
>          Components: General
>    Affects Versions: 2.0.5
>            Reporter: Matt Benson
>         Attachments: mf3119.patch.txt, mf3119.tar.gz, mf3119.tar.gz
>
>
> As reported in MYFACES-2466 (whose summary I copied here), I am encountering 
> the NPE on the access of holderList in what is currently line 1917 of 
> UIComponentBase whenever I use a ComponentSystemEventListener on UIViewRoot.  
> Specifically I am subscribing to PreRenderViewEvent and the problem occurs 
> restoring the view regardless of whether I unsubscribe the listener e.g. 
> after RENDER_RESPONSE.
> More information:
> _systemEventListenerClassMap is null when the method is called, thus the map 
> is reinstantiated so of course the value looked up and assigned to holderList 
> is null.
> Now I have to go use Mojarra until this is fixed.  :(

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to