0

I'm wondering why there is no single notice about the importance of immutability property when storing serializable objects in the HTTP session? I tried to check the JSF and Servlet API specifications but couldn't find anything related.

I've seen a specific problem in the case of JSF based clustered application where @SessionScoped managed bean is mutable i.e. user-modified parameter is stored as a field of this managed bean.

Trouble begins when the node "owning" the session (thanks to stickiness requirement in servlet API specs) dies and different node starts to take over serving the session, the latest state is lost. In fact, only the initial state is replicated. I believe this is because managed beans are placed in session (and replicated to backup nodes) only when they are created for the first time, at least this is confirmed by my tests performed on Websphere.

While one can debate whether this is a good design or not, JSF and even Servlet API still allows it to happen.

I also found some note in Oracle docs:

As a general rule, all session attributes should be treated as immutable objects if possible. This ensures that developers are consciously aware when they change attributes. With mutable objects, modifying attributes often requires two steps: modifying the state of the attribute object, and then manually updating the session with the modified attribute object by calling javax.servlet.http.HttpSession.setAttribute(). This means that your application should always call setAttribute() if the attribute value has been changed, otherwise, the modified attribute value will not replicate to the backup server.


Apart from manually updating the attribute as described above, is there any clean solution, preferably in an idiomatic JSF way?

tsobe
  • 179
  • 4
  • 14
  • 2
    To exclude the one and other, do you have `distributable` flag enabled in `web.xml` as indicated in the currently accepted answer to this related question? https://stackoverflow.com/q/35102645 If not then you may indeed run into the described problem (and actually much more such as broken view scoped beans as indicated in that related question). If you already have set it, then your problem is in the end indeed most likely related to a WebSphere-specific config as indicated in the answer of Allan here below. – BalusC Jan 20 '20 at 18:02
  • @BalusC. I just noticed there is no distributable flag in web.xml, but it seems that Websphere still enforces session stickiness most of the time. However, as mentioned in the link you provided, I do see VEEs sometimes, and as per my observation, it happens when I try to emulate the node failure. Viewstate is stored at the server-side for the record. I'll give a try to set the distributable flag! – tsobe Jan 21 '20 at 10:11
  • Servlet spec says to set distributable flag when you want to deploy WAR to a cluster. This will among others ensure that libraries such as JSF are aware of this and pay extra attention to this which is otherwise unnecessarily expensive in a non-cluster environment. – BalusC Jan 21 '20 at 10:42

1 Answers1

1

In WebSphere Liberty, there is a property called writeContents = "GET_AND_SET_ATTRIBUTES" for the mutable session objects. For details, please see:

https://github.com/OpenLiberty/open-liberty/issues/2802

https://www.ibm.com/support/knowledgecenter/en/SSEQTP_liberty/com.ibm.websphere.liberty.autogen.nd.doc/ae/rwlp_config_httpSessionCache.html

Same property apply for database persistence.

  • Thanks Allan. Is this available in Liberty only? Any alternatives in traditional Websphere 8.5 or 9? Out of curiosity, how is this implemented? How does the container know that attribute value (object) was mutated? – tsobe Jan 21 '20 at 10:02
  • That is correct, GET_AND_SET_ATTRIBUTES replicate is only available in Liberty. Traditional Websphere still relies on application to call setAttribute (ONLY_SET_ATTRIBUTES). – Allan Zhang Jan 21 '20 at 17:21
  • Container won't know the attribute value object was mutated. GET_AND_SET_ATTRIBUTES option simply replicate all attributes for which getAttribute is invoked (even without setAttribute calls). – Allan Zhang Jan 21 '20 at 17:37
  • Apparently this is also possible in traditional Websphere as described [here](https://www.ibm.com/support/knowledgecenter/SS7K4U_8.5.5/com.ibm.websphere.zseries.doc/ae/uprs_rtuning_custom.html), but I couldn't make it work yet – tsobe Jan 23 '20 at 15:57
  • For traditional Websphere, you have to select "All session attribute" in Write contents option for mutable object. – Allan Zhang Jan 24 '20 at 19:26