I have a Struts based web application that has a structure similar to the one shown below. (Not this is just an example)
$TOMCAT_HOME/webapps/myapp
|-css
|-myapp.css
|-js
|-myapp.js
|-forum
|-index.jsp
|-list.jsp
|-users.jsp
|-Articles
|-index.jsp
|-ListArticles.jsp
|-Guestbook
|-viewGuestBook.jsp
|-AddnewEntry.jsp
|-WEB-INF
|-classes
com
|-myapp
|-forum
|-DisplayForum.class
|-ListUsers.class
|-article
|-ArticleList.class
|-AddArticle.class
|-guestbk
|-LoadGuestBook.class
|-ProcessGuestBook.class
Currently, the application is built using ANT and deployed to the Tomcat application server as a single war file (named myapp.war). I would like to separate the application so that it is deployed using multiple war files for each module. (i.e. forum.war, articles.war and guestbook.war). The contents of the new war file will only contain files related to the module. For example, the forum.war file will contain
$TOMCAT_HOME/webapps/forum
|-forum
|-index.jsp
|-list.jsp
|-users.jsp
|-WEB-INF
|-classes
com
|-myapp
|-forum
|-DisplayForum.class
|-ListUsers.class
There are a couple of things i am not sure about with this approach.
Shared static resources
The *.css and *.js files are common across each war file. If i have different war files i will have a copy of the css files in each war file. Is there any way i can deliver the resource files (css, js, static files) in a common approach so that they are shared. I am thinking that maybe i should include a new war file called common.war and include the shared static data. (I think the other war files can access these files using the URL as they are static resources. right?)
Shared classes
There are some classes that are shared globally. As an example, there is a class called UserSession
. When the user logs-on to the application, the UserSession object is created and stored in a Hashtable and the user's session id as the key for the Hashtable. Anytime a user tries to acess any part of the application, the session id is checked against the sesion id's in the Hashtable.
The UserSession object does a number of things - such as
- Validating user login
- Track user's activity
- Log user login history to the database
- And more...
I need all war files (applications/modules) to have access to the UserSession
object but that only one is associated with each session. How should i architect this so that the user's session spans across the different war files?
I have been reading around about how to share objects and came up with two options
- Shared object via JNDI
- Shared object via Tomcat ServletContext
As i understand it, if an object is stored in the ServletContext
, it can be accessed by any application (i.e. war file). How would this work though if i want a different instance per user session. For example,
User1 logs on - UserSession stored in ServletContext User2 logs on - Where do i store User2's UserSession object?
At the moment i store the sessionID in HTTPSession
and the UserSession
object in a HashTable.
HttpSession session = request.getSession(true);
UserSession userSession = getUserSession(session.getId());
Does User1 get the same sessionId regardless of the war file he/she is accessing? If so Could i Store another List object in ServletContext
that contains the sessionIDs?
I have also seen references to object sharing using JNDI. I am not very familiar with JNDI. I have used JNDI for DataSources but that is as far as it goes. How exactly would it work? I would appreciate if someone can point me to an example showing how JNDI can be used for sharing data. Is it true that JNDI is the better approach and why?
And finally, where would the UserSession.class
file reside? I know i can put it in a jar file in $TOMCAT_HOME/lib
but this is usually not recommended. The problem though is if it is in the WEB-INF/lib
folder of one of the war files it cant be accessed by any other war file.
Would appreciate some input/suggestions. I would be interested to know what strategy you use to deploy an application made up of multiple war files.
Thanks
Edit
Ok i forgot to mention why i want to split the war file. Basically, we have several teams of developers. We have had situations where one team is working on a specific area of the application and another team is working on a different area.
For example assume the following scenario -
Team1 is working on the Forums module due to be released next month. Team2 has been asked to deliver a change for the Articles and should be released next week.
If Team1 has checked in their code and are performing system/integration tests which will take more than a week, Team2 is stuffed as they have to wait.
These kinds of problems are usually solved using Branching but we tend to avoid branching as it introduces a lot of complications with merging that we decided to avoid Branching.
The other reason is that we have an older application that i am considering to reuse with this application. The older application based on pure HTTPServlet. I.e not based on any framework (i.e. structs, spring etc). If i want to integrate it with my existing app i will need to use the session/servletcontext.
Also, a lot of people are skeptical of the fact that if you make a simple change (e.g. you add a new stylesheet definition to a single css file), you have to rebuild and redeploy the whole application.
Other reasons include
- Could Simplify scalability/load balancing - (possibly?) Not sure about this one. I am thinking in terms of deploying each war file to a different server/cluster.
- Reduces PERMGEN memory requirements
- etc...