Showing posts with label tomcat. Show all posts
Showing posts with label tomcat. Show all posts

Friday, May 20, 2011

JSF sharing across multiple WARs in JBoss/Tomcat

This will be where I keep notes until I have a final solution. Then I'll reformat.

If someone decides that your application should be split up between more than one WAR, but they need to share some data such as User information (even just a logged in token or something), you have to find your own solution as this is not supported by the J2EE spec.  So far I've decided to do some sharing by making one of the WARs (we'll likely have 4 by the end) the one that holds the shared content.  I'll call it 'war1'.  In JBoss/Tomcat, this will give it a context name of '/war1'.  So, in 'war2', we need to look up the /war1 context and grab info out of its session.  I'll give some more detail.

In JBoss/Tomcat, there is a property in the server.xml called crossContext.  Depending on your JBoss/Tomcat version, it may be split into separate config files.  For example, in my JBoss 5.1, the actual config file is C:\jboss-5.1.0.GA\server\default\deploy\jbossweb.sar\context.xml.  You'll need to set this property to true.  The default is true in JBoss 5.1.  I don't know about other versions or standalone Tomcat.  Setting crossContext=true will allow us to lookup contexts from other contexts.

To set something in the shared context, I've done this: (this is in war1)

HttpServletRequest request = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
request.getSession().getServletContext().getContext("/war1").setAttribute("shared", shared);


In war2, we get it out similarly:

HttpServletRequest request = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
ServletContext medicalportal = request.getSession().getServletContext().getContext("/war1");
Object s = medicalportal.getAttribute("shared");


Ideally, I would like to have a context dedicated to sharing: /shared.  Then all wars would go to the same spot for sharing.  This is all in an EAR; so, we have a jar with some JSF code.  We can shove the shared context accessing code there so that we can have code like this:

FacesUtility.setSharedAttribute("name", value);
Object value = FacesUtility.getSharedAttribute("name");


An over-the-top solution but way cool would be to have a JSF variable resolver that would look in the shared context for beans.  ...  Actually, that might not be over the top.  It would make the code much less complex.