Search code examples
jsfserializationjsf-2viewstatemojarra

Server-state serialization in a session in Mojarra


Going through an abstract in a book, I came across this:

On the server side, the state can be stored as a shallow copy or as a deep copy. In a shallow copy, the state is not serialized in the session. By default, JSF Mojarra uses shallow copy.

I seriously couldn't understand this.

Since in the above case, we will have-

javax.faces.STATE_SAVING_METHOD set to server,

and an input hidden field javax.faces.ViewState with a value somewhat like this "2870966362946771868:-8449289062699033744".

Obviously, the server must have maintained internally an state corresponding to the above hidden field.

But going by the abstract, if the state is not serialized in the session, then where it is?

Furthermore, I have noticed one thing that if my Managed bean(ViewScoped) is not implementing marker interface Serializable with STATE_SAVING_METHOD set to server, then in Mojarra, the NotSerializablEexception doesn't occur, while in MyFaces it does.


Solution

  • But going by the abstract, if the state is not serialized in the session, then where it is?

    It exist of references to instances already in the HTTP session which in turn is not necessarily serialized.

    The key context param for this is javax.faces.SERIALIZE_SERVER_STATE which defaults in MyFaces to true and in Mojarra to false. When set to true, you will sooner see NotSerializableException on artifacts which are mistakenly not Serializable. Otherwise, you're dependent on server configuration. For example, Tomcat by defaults serializes the entire HTTP session including all its attribtues during a server restart. Some servers, particularly those running in cluster, can even be configured to serialize entire HTTP sessions during runtime. In such cases you would also see NotSerializableException during restart or failover.

    Mojarra has plans to make javax.faces.SERIALIZE_SERVER_STATE setting default to true as per 2.3, particularly because this setting would proactively prevent unforeseen developer mistakes such as assigning non-serializable instances of JSF artifacts such as UIComponent or even FacesContext as properties of a non-requestscoped bean. It would otherwise result in problems as Stuck thread at UIComponent.popComponentFromEL, Java Threads at 100% CPU utilization using richfaces UIDataAdaptorBase and its internal HashMap and java.lang.IllegalStateException at com.sun.faces.context.FacesContextImpl.assertNotReleased.

    On the other hand, in older MyFaces versions, this setting broke EJBs injected in serializable managed beans due to the wrong classloader being used to resolve EJB proxies during deserialization. This was fixed in MyFaces 2.0.15 and 2.1.9 as per MyFaces issue 3581. See also @EJB in @ViewScoped @ManagedBean causes java.io.NotSerializableException.