You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by Michael Concini <mc...@gmail.com> on 2010/06/11 16:06:45 UTC

state saving change proposal

All,
I've got a bug that one of our testers found where we behave differently 
from the RI.  Let me lay out the situation and the two options I have 
come up with for solutions.  This applies to at least the 1.2.x and 
2.0.x releases.

The application has a simple logout.jsp that we get to via a navigation 
rule (e.g. when outcome == "logout").  This is a simple JSP, no JSF 
tags, which contains a scriptlet that clears login data, invalidates the 
session and then redirects to a plain html page.  Its a fairly simple 
scenario that works without issue on the RI.

On MyFaces, when processing logout.jsp, we end up trying to create a new 
session because we try to save the state.  This isn't kosher since the 
response has been committed already so you'll get an 
IllegalStateException on Tomcat.

After much debugging and doing some black box testing of the RI behavior 
this week, I think I've finally figured out that the difference is that 
the RI appears to only be doing state saving if there is a JSF form tag 
on the page.  By simply adding a form tag to logout.jsp I can recreate 
the IllegalStateException.

I've got two potential solutions for this.  Either one should work but 
I'm interested to know if there is a preference in the community about 
which way to go or if there is another alternative to consider.

1) add a check to make sure that either there is session or if one needs 
to be created that the response has not been committed in 
JspStateManagerImpl.saveSerializedView().  If there is no session and 
the response has been committed, just return null back through 
StateManger.saveView() which indicates no state information to be saved.

2) do something in the form renderer to indicate that the state needs to 
be saved, maybe setting a request attribute that can be checked in 
saveView to determine whether to actually save state or just return null.

I've tested out the first option already and it does resolve the issue 
and in some initial testing does not cause any regressions elsewhere.  
Obviously a thorough testing would be done prior to actually integrating 
the change if we go that way.  I have not coded up a fix yet for the 
second option so I haven't done any testing on it yet.

As far as my preference, I'd lean a little towards the first as it seems 
to be a little less at risk of breaking anything else since we're really 
limiting the instance where we don't try to save state to only if there 
is both no valid current session and the response has already been 
committed.

The second change seems a little higher risk, but also potential higher 
reward.  This change would from what I can tell bring us into more 
consistent behavior with the RI and also have a potential slight 
performance gain by not performing state saving on JSF pages that do not 
contain form elements (as well as any non-JSF JSP pages that have been 
pushed through the JSF lifecycle due to navigation rules, etc).  The 
risk of course being that the change affects many more pages since it 
will prevent state saving on any pages that don't contain a form element.

The other question then would be whichever option we go with, should we 
apply it to both 1.2.x and 2.0.x or just to the 2.0.x releases?  I'm not 
sure that I would want to apply #2 into such a mature stream as 1.2 but 
would feel more comfortable applying #1 to both.

Apologies for the wordiness here.

Regards,
Mike


Re: state saving change proposal

Posted by Michael Concini <mc...@gmail.com>.
Leo,

So I just did a little digging through the facelets code, and it looks 
like in the facelets case, we already are doing something similar to 
what you are proposing.  ViewHandlerImpl's writeState method looks like 
it only gets called by the encodeEnd on HtmlFormRendererBase.  So I 
think we are probably ok in the facelets case.

The problem as far as I can tell would only be one that affects JSP.  
This might actually make the change simpler as we might be able to 
re-use some of the logic from facelets and update the JSP view handler 
to function the same way.   The key appears to be in the call to 
StateWriter.getCurrentInstance().writingState(); and the subsequent 
check by the facelets VDL to StateWriter.isStateWritten() to determine 
whether or not to save the state.  We don't do such a call in the 
JSPViewHandler.

regards,
Mike

On 6/11/2010 12:29 PM, Leonardo Uribe wrote:
> Hi
>
> In theory, if there is no form there is no state saved, so the ajax 
> received will not have the state and no postback could be sent. Ok, if 
> the view state is saved in some different way by other alternate ajax 
> component, the point in common is that any component that writes the 
> state should call viewHandler.writeState() method (and 
> stateManager.writeState() method).
>
> Instead do something on the renderer, I think it is possible to do 
> something on viewHandler.writeState() or stateManager.writeState() and 
> keep the same proposed behavior. In jsf 2.0, we have to keep into 
> account the method getViewState().
>
> regards,
>
> Leonardo Uribe
>
> 2010/6/11 Werner Punz <werner.punz@gmail.com 
> <ma...@gmail.com>>
>
>     What about ajax and http get which perse do not post a form in all
>     cases
>     but can post data back into the lifecycle?
>
>     OK,http get is handled, but still there is ajax which can trigger
>     a  post without a form.
>
>
>
>     Werner
>
>
>     Am 11.06.10 16:13, schrieb Martin Marinschek:
>
>         Hi Mike,
>
>             2) do something in the form renderer to indicate that the
>             state needs to be
>             saved, maybe setting a request attribute that can be
>             checked in saveView to
>             determine whether to actually save state or just return null.
>
>
>         I would lean towards option 2 - I don´t see how the saved
>         state would
>         be used at all if there is no form on the page - there cannot be a
>         postback to it, so this memory is anyways wasted.
>
>         best regards,
>
>         Martin
>
>
>
>


Re: state saving change proposal

Posted by Leonardo Uribe <lu...@gmail.com>.
Hi

In theory, if there is no form there is no state saved, so the ajax received
will not have the state and no postback could be sent. Ok, if the view state
is saved in some different way by other alternate ajax component, the point
in common is that any component that writes the state should call
viewHandler.writeState() method (and stateManager.writeState() method).

Instead do something on the renderer, I think it is possible to do something
on viewHandler.writeState() or stateManager.writeState() and keep the same
proposed behavior. In jsf 2.0, we have to keep into account the method
getViewState().

regards,

Leonardo Uribe

2010/6/11 Werner Punz <we...@gmail.com>

> What about ajax and http get which perse do not post a form in all cases
> but can post data back into the lifecycle?
>
> OK,http get is handled, but still there is ajax which can trigger
> a  post without a form.
>
>
>
> Werner
>
>
> Am 11.06.10 16:13, schrieb Martin Marinschek:
>
>  Hi Mike,
>>
>>  2) do something in the form renderer to indicate that the state needs to
>>> be
>>> saved, maybe setting a request attribute that can be checked in saveView
>>> to
>>> determine whether to actually save state or just return null.
>>>
>>
>> I would lean towards option 2 - I don´t see how the saved state would
>> be used at all if there is no form on the page - there cannot be a
>> postback to it, so this memory is anyways wasted.
>>
>> best regards,
>>
>> Martin
>>
>>
>
>

Re: state saving change proposal

Posted by Werner Punz <we...@gmail.com>.
What about ajax and http get which perse do not post a form in all cases
but can post data back into the lifecycle?

OK,http get is handled, but still there is ajax which can trigger
a  post without a form.



Werner


Am 11.06.10 16:13, schrieb Martin Marinschek:
> Hi Mike,
>
>> 2) do something in the form renderer to indicate that the state needs to be
>> saved, maybe setting a request attribute that can be checked in saveView to
>> determine whether to actually save state or just return null.
>
> I would lean towards option 2 - I don´t see how the saved state would
> be used at all if there is no form on the page - there cannot be a
> postback to it, so this memory is anyways wasted.
>
> best regards,
>
> Martin
>



Re: state saving change proposal

Posted by Martin Marinschek <mm...@apache.org>.
Hi Mike,

> 2) do something in the form renderer to indicate that the state needs to be
> saved, maybe setting a request attribute that can be checked in saveView to
> determine whether to actually save state or just return null.

I would lean towards option 2 - I don´t see how the saved state would
be used at all if there is no form on the page - there cannot be a
postback to it, so this memory is anyways wasted.

best regards,

Martin

-- 

http://www.irian.at

Your JSF powerhouse -
JSF Consulting, Development and
Courses in English and German

Professional Support for Apache MyFaces