12

I have seen several developers looking for a solution for this problem: accessing session information from a different WAR (even when inside the same EAR) - here are some samples: Any way to share session state between different applications in tomcat?, Access session of another web application, different WAR files, shared resources, Tomcat: How to share data between two applications?, What does the crossContext attribute do in Tomcat? Does it enable session sharing? and so on...

From all I have searched, there are some specific solutions depending on the container, but it is somehow 'contrary to the specification'. I have also looked through Java EE specification without any luck on finding an answer.

Some developers talk about coupling between web applications, but I tend to disagree. What is the reason one would keep WARs inside the same EAR if not coupling? EJBs, for instance, can be accessed locally (even if inside another EJB JAR within the same EAR).

More specifically, one of my WARs handles authentication and authorization, and I would like to share this information with other WARs (in the same EAR). I have managed to work around similar problems before by packaging WARs as JARs and putting them into a singular WAR project (WEB-INF/lib). Yet I do not like this solution (it requires a huge effort on servlet naming and so on).

And no solution has answered the first (and most important) question: Why can't WARs share session information?

rvcoutinho
  • 576
  • 1
  • 3
  • 10
  • 1
    Not sure why this was downvoted, other than it might be a better fit for SO. – NateDSaint Dec 04 '12 at 21:29
  • 3
    "In accordance with the servlet 2.3 API specification, the session manager supports session scoping by Web module only. Only servlets in the same Web module can access the data associated with a particular session." This can be seen again in [HttpSession](http://docs.oracle.com/cd/E17802_01/products/products/servlet/2.5/docs/servlet-2_5-mr2/javax/servlet/http/HttpSession.html) - "Session information is scoped only to the current web application (ServletContext), so information stored in one context will not be directly visible in another." - Doing so is contrary to the specification. –  Dec 04 '12 at 22:00
  • (better, current link for [HttpSession](http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpSession.html) ) –  Dec 04 '12 at 22:06
  • @MichaelT, thank you. But it still does not answer why. – rvcoutinho Dec 04 '12 at 23:56
  • @NateDSaint Even though the question is related to specific technologies, I believed it was more likely to be a conceptual question. Then, I decided for Programmers. – rvcoutinho Dec 05 '12 at 00:05
  • @rvcoutinho that's why its not an answer. The specifics of the 'why' are speculation into the minds of those who wrote the spec. Occasionally with big name technologies you can find the memoirs of the decision making process (the design of Java is reasonably documented). This is unlikely the case for servlet api. –  Dec 05 '12 at 14:26

4 Answers4

7

Treat an EAR like a pseudo-virtual machine

An EAR is simply a collection of WAR files that share common configuration and libraries, usually from JARs. This enables a collection of inter-dependent services to be managed more easily within an application container. Thus you can think of an EAR as a simple form of virtual machine once it is deployed into its container.

In the same way that one process on a virtual machine cannot affect another, the same is true for an EAR. All the WARs are isolated to protect their internal state.

Scaling authentication

In general web applications need to be stateless to scale well. Having a lot of information in the session is an anti-pattern that prevents this. This leads to a conflict between the stateless nature of HTTP and the need to maintain a speedy, customised user experience. Authentication is a classic use case, and is prevalent in chatty APIs that require a lot of authenticated requests to deliver end-user functionality.

Single Sign On and Single Sign Off need careful signalling to work correctly (consider partial Sign Off), particularly when horizontal scaling is in place. Simply sharing session state is almost never a good solution and a better approach is to use a single point of reference for the user information that all nodes in the cluster have access to.

Concentrating on speedy cached access to relevant information will yield far more scalable results than some complex, fragile session sharing solution.

Gary
  • 24,420
  • 9
  • 63
  • 108
  • Thanks, @GaryRowe. This is the answer I was looking for. Anyway, could not that be for the developer to decide? – rvcoutinho Dec 05 '12 at 12:46
  • Another question: Would you think JBoss Cache might be a good solution? Have you heard of Apache Shiro (and its session clustering)? What about it? – rvcoutinho Dec 05 '12 at 12:48
  • @rvcoutinho Does the application developer decide how processes are managed in the Linux kernel? It's a similar framing of a question - yes, you could do it but it's going to be extremely hard and probably cause you more pain than taking the alternative path. – Gary Dec 06 '12 at 09:57
  • 2
    @rvcoutinho I've not used Apache Shiro (aka Apache Security) but I imagine that it would be a good solution to the shared security issue. Definitely consider integrating with OpenID and OAuth2 rather than rolling your own protocol to achieve the same thing. JBoss Cache is by their own admission in a dead end being replaced with Infinispan which looks rather complex. You might want to take a look at the [Twelve-Factor App site](http://www.12factor.net/) for a glimpse of a simpler more scalable solution. – Gary Dec 06 '12 at 10:05
2

Well, AFAIKS, there's no real reason why you'd like to do this. A WAR is a self contained web application, with it's own (web application specific) scopes (like session scope). If you need to share functionality (Java code, JSP pages, CSS files), between multiple WARs you have the far more sensible option of packaging them as JAR files and deploying them in your application server. A WAR package is a more complex packaging solution, and one designed to encapsulate something different than simple "common code/functionality". The JAR is a simpler format AND is designed for packaging and sharing code and functionality. Why would you want to use a more complex and not-specificaly-designed-for-that packaging to share something, when you have have a simpler and more-suited-to-that package format already available. Think of JSTL Tags, Struts JQuery Plugin, Spring security, they all come as JARs.

Shivan Dragon
  • 4,583
  • 5
  • 24
  • 31
  • I agree with you. But only when it comes just to general resources. But, for a single sign-on application, I would need to share session specific information (about the logged user). And I see no reason why this would be against the spec. – rvcoutinho Dec 04 '12 at 23:59
  • 2
    Because session scope is not made to share current user data between different applications. And because SSO implies more than inspecting session scope attributes. You can make and package code outside your war (and which would not depend upon your war, but rather have the war depend on it) that would access session scope attributes if you wanted (like a filter), but the better solution IMHO would be to have a separate facade application or server configuration that deals with auth, and grants access to other (war deployed) applications. – Shivan Dragon Dec 05 '12 at 00:33
  • I would again agree with you. Yet the JavaEE specification (using JAAS) holds the user information as part of the HttpSession, which is opposed to this approach. One of the reasons I have been considering to use Shiro (it maintains an orthogonal session) instead. – rvcoutinho Dec 05 '12 at 02:31
  • Anyway, thanks for the response. I still do not have a definitive answer for my question, but all you have said is relevant. +1 – rvcoutinho Dec 05 '12 at 02:35
  • @rvcoutinho well, that's my opinion on the matter, sorry it wasn't more helpful to you. – Shivan Dragon Dec 05 '12 at 07:26
2

It's something that I think is missing functionality from the JEE EAR specification - the ability to share web sessions across multiple web archives bound within an EAR.

App servers such as Weblogic have non std implementations for this functionality.

Martijn Verburg
  • 22,006
  • 1
  • 49
  • 81
0

I think this was done on purpose, to avoid different web apps accidentally overwriting each others session information. It might come handy in your case, but in general, you don't want users to make the app crash or escalate their privileges just because they use two web apps at the same time. It's not exactly difficult to explicitely share information between web apps; just make a class with a static HashMap, use GUIDs as keys and transfer them as part of the URL or HTTP parameter.

user281377
  • 28,352
  • 5
  • 75
  • 130
  • Thanks. Actually, I was not talking about sharing the whole session between every application, but specific session information (as user info) when needed. Maybe I was not clear. Any suggestions on making it clearer? – rvcoutinho Dec 05 '12 at 12:33