I am trying to write a simple program where i can put a HashMap on an application scoped session and get two applications/contexts deployed as two war files access the HashMap.
Servlet 1
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException{
PrintWriter out = response.getWriter();
HashMap<String ,String> hm = new HashMap<String, String>();
hm.put("1", "1");
this.getServletContext().setAttribute("usermanager", hm);
this.getServletConfig().getServletContext().setAttribute("usermanager2", hm);
}
Servlet 2
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException{
HashMap newMap2 = (HashMap) this.getServletConfig().getServletContext().getAttribute("usermanager");
HashMap newMap3 = (HashMap) this.getServletContext().getAttribute("usermanager2");
System.out.println("newmap2 size " + newMap2.size());
System.out.println("newmap3 size " + newMap3.size());
}
To test this i restarted Tomcat 6 then run access Servlet 1 first so that it initializes the Hashmap object. When i subsequently access Servlet 2 i get a NULL-POINTER error which is pointing at the line number where i tried to call newMap2.size()
What am i doing wrong?
java.lang.NullPointerException
at com.TestServlet.doGet(TestServlet.java:24)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:291)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:619)
As @Peter Cetinski already mentioned a Servlet Context always relates to exactly one web application (WAR file). Nevertheless, the Servlet API provides a way to access ‘foreign’ Servlet Contexts by calling
javax.servlet.ServletContext.getContext(uriPath).So if you really want/need to spread your Servlets across different WARs and communication between them is required, you can do this.
Assuming that Servlet 1 is located in web application warA, Servlet 2 located in web application warB, and the applications context path is the same as the web application name (e.g.
http://myserver/warAandhttp://myserver/warB), the code for Servlet 2 could look like this:There are some constraints:
you must explicitly allow
warBto access the foreign context by specifying this in the applications’context.xml:<Context crossContext="true"/>this setup is proprietary (I cannot tell you how this works in other application servers/servlet engines)
if you want to share custom classes they must be shared between the applications (place them in
<tomcat>/libin the standard setup you work with different classloaders for
warAandwarB, you should be aware of thatTomcat does not guarantee a certain startup sequence (there is no way to configure this). In your case
warBmust be able to handle this and expectwarAto be not yet startedIf you need to share objects/information between web applications, I’d consider those alternative approaches:
a shared singleton located in Tomcat/lib (I know a singleton, but it works)
an object located in the JNDI tree (Tomcat documentation)
information required to build the cache in a shared data store (file, database, etc.) and each applications loads the data at startup