I feel that your question was a little misunderstood and that you already had a basic understanding of the API, i.e. when a web application sets its crossContext="true" , it can use getContext() to access a context that matches any other -app network deployed to the server.
getServletContext().getContext() equals NULL unless <Context crossContext="true">
From what I understood, your question actually is that in /SameWebApp why
ServletContext context1 = session.getServletContext(); context1.setAttribute("contextAttribute", new Object()); ServletContext context2 = session.getServletContext().getContext("/SameWebApp"); System.out.println(context1.equals(context2)); // prints false, or System.out.println(context2.getAttribute("contextAttribute")); // prints null (at least they could have been clones)
In one word, the answer is "Security." Imagine if you could not guarantee that the "adminEmail" context attribute was not tampered with by an evil web application that has crossContext=true . Your application can potentially help to compromise yourself as soon as the request "Forgot your password" appears! :)
Dive into the interior of Tomcat
Tomcat 7 provides the class ApplicationContext implements ServletContext , which returns with getContext("/context-root") as
if (context.getCrossContext()) { // If crossContext is enabled, can always return the context return child.getServletContext(); } else if (child == context) { // Can still return the current context return context.getServletContext(); } else { // Nothing to return return (null); }
Here, context belongs to the current web application, and child represents another web application. But hold on, what makes Tomcat call it a kid?
These two are not actually ApplicationContext , but instances of the StandardContext class, which implements Context , but instead of servlet-specific things, contain specific Tomcat configuration settings for a web application such as crossContext, hostname, mimeMappings, etc. StandardContext.getParent() gives you a Container and therefore it is referred to as a child of the above.
In any case, we are interested in the case when child == context true, i.e. getContext() was called on "/ SameWebApp ". The call is delegated to StandardContext.getServletContext() , which was implemented to return another instance from ApplicationContext .
This is why the attributes set in context1 are not found in context2 .
But wait, one more thing. Why is StandardContext.getServletContext() returned as
return (context.getFacade());
A Tomcat instance basically runs two types of Java code:
The container code is "Trusted" and can sometimes run with elevated privileges. On the other hand, the user code is not reliable and should be limited from compromising the internal components of Tomcat.
One of the things Tomcat does for this is always to include the ApplicationContextFacade around the ApplicationContext (and therefore StandardContext ). Therefore, just to remind you that the simple implementation of ServletContext is actually a StandardContext mapped to ApplicationContext , which is then wrapped in ApplicationContextFacade .
For more information on how ApplicationContextFacade works by using Reflection in tandem with the Globals.IS_SECURITY_ENABLED and SecurityUtil.isPackageProtectionEnabled() settings, see Why servlets access Tomcat ApplicationContext through a facade on SO.
References:
Tomcat 7 source code (download link)