Session state in Java Web application is associated with a single (user) browser session on the one hand and typically with a specific web application on the other (server side) hand. Session state is created and maintained in the context of a usually a single web application. However…
We ran into a situation where our web application was assuming gigantic proportions. To complex to quickly deploy or even easily build, compile and test. On closer inspection, it was quickly revealed that the application really consisted of a number of relatively independent modules – say one for each of the options in the main menu and one for the entry point – main menu, login, manage user preferences etc. From a functional point of view, the big web app monster was by and large a collection of almost individual web applications. Almost because a substantial number of navigations took place between pages in these modules. And some context data – including credentials – should be passed on these navigations. The application was developed with such information stored in the session scope – as all modules always have access to a (shared) session scope, it was thought.
We got to the point where for many reasons we would like the big fat web application to be split in one web application per module. This would allow much easier development, administration, release management etc. However, we could not resolve this issue of shared session state that should be maintained across the web applications-per-module.
We contemplated moving this shared session state to a memory grid – but the impact on the existing application would be quite substantial (although an interesting challenge: introduce a new scope for managed beans (superapplication, cross-application or application-cluster) and create an EL resolver that knows where to find beans referred to with expressions like #{super-application.bean.property}; find a way for all applications in the applicationcluster to identify a user session in the same way to ensure the bean instance associated with the current session in the current application is retrieved).
An easier solution presented itself – after briefly conferring with Mike Lehmann of Oracle’s Application Server team – in the form of WebLogic Server’s session sharing capabilities.
With Session Sharing enabled in WebLogic Server, web applications are clustered in a sense that they share session state – which basically means they use the same SessionId for a user’s browser session. The Map that holds the user session specific data is the same for all web applications deployed to a WebLogic Server with session sharing enabled.
Data collected in the session when the user access Web Application A is accesible when the user starts accessing – from the same browser session – Web Application B, and vice versa.
The criteria or steps for enabling this are qiute simple:
All Web Applications that are to share session state
- need to be deployed in the same EAR file (ouch, still a single big deployment step)
- need to have a deployment descriptor in their weblogic-application.xml with this setting:
<session-descriptor> <sharing-enabled>true</sharing-enabled> </session-descriptor>
Note: session sharing is not partial. There is no shared compartment in addition to an application specific, private session scope.
Also note that much of each application’s definition can be deployed in a WebLogic Shared Library; these libraries (one per web application) can be deployed independently of the EAR file. So deployment does not have to be as massive as suggested above.
An example of Shared Session state between two web applications
There are two very simple java web-applications W1 and W2. Both contain class SomeBean and both have a JSF Managed Bean configuredv- someBean – in session scope. This bean will be accessible in both W1 and W2 – the same instance that is thereby shared.
Both application have the weblogic-application.xml deployment descriptor file. In the session tab the checkbox Enable session sharing has been checked.
This corresponds with the following XML content
The EAR file that will be deployed contains both Web Applications:
The EAR file contains a META-INF directory with:
In this case, I have constructed the EAR file using jZip.
The application.xml file configures both web applications, refering to their respective war-files in the EAR:
The weblogic-application.xml file is the same as was previous created and described.
After deployment of the EAR file, both Web Application should be enabled. Let’s access the Form page in W1:
This page contains a form that is bound to the someBean session scope managed bean. Enter some values and post the data to the server.
Using the hyperlink – or by typing the URL in the location bar – navigate to Web Application W2.
A similar page opens in W2. This page also contains items that are bound to a managed bean someBean. This bean was defined in session scope in W2 and because a bean with the same name was configured also in session scope in W1 and because W1 and W2 share their session state, the values posted on someBean in W1 are available when the page bound to someBean in W2 is accessed:
Making a change in W2:
followed by navigation back to W1 results in:
Of course the changes applied in W2 to the session scope someBean are now visible in W1 as well – because W1 and W2 have the same someBean instance from their shared session scope.
Hi Lucas
Thanks for this post , it is very useful.
we have enabled session sharing but we are not able to retrieve session managed bean used in one web module to other. will u please describe how u have used same session bean in 2 different pages of different modules.
Hi Lucas
Thanks for this post , it is very usefull.
Can you please expand on the following statement
“Also note that much of each application’s definition can be deployed in a WebLogic Shared Library; these libraries (one per web application) can be deployed independently of the EAR file. So deployment does not have to be as massive as suggested above.”
How would this work given your example above?
Is there no getting around the requirement that one EAR must contain all web applications where session sharing is required?
Thanks.
Hi Lucas,
Thanks for the detailed post. We are also running into a similar situation but in our case we want “Web1” war file to be deployed in one cluster and “Web2” war file to be deployed in another cluster. Will the same configuration work in our case??
Thanks,
Hi Lucas
Did Mike not talked about Coherence*Web? This gives you an even more reliable and robust session sharing.
You can use some coherence specific context parameter settings like enable session context, session length and caching possibilities.
Hi Michel,
Mike did indeed mention Coherence*Web. However, that requires a more than basic license model. In addition: is Coherence*Web meant just for session state sharing between cluster nodes (as well as fast serialization for single node systems) or is it also intended as a mechanism to share the session state between different web application – as I am looking for in this post?
Of course Coherence and any other Data Grid (or even any Static HashMap in the JVM for single node systems) can be used to store, retrieve and therefore share data – however, then the burden of managing some data in the session and other data on the grid is on the developer. With the approach described in this article, the session state is just shared without additional overhead.
Lucas