Do servlet containers prevent web applications from causing each other interference and how do they do it?
The short answer is that the servlet container isolates the applications by using a separate classloader for each application - classes loaded by separate classloaders (even when from the same physical class files) are distinct from each other. However, classloaders share a common parent classloader and the container may provide a number of other container-wide resources, so the applications are not completely isolated from each other.
For example, if two applications share some common code by each including the same jar in their war, then each application will load their own instance of the classes from the jar and a static variable (e.g. a singleton) of a class in one application will be distinct from the static variable of the same class in the other application.
Now, take for example, that the applications try to use java.util.Logger
(and presumably don't include their own instance of the Logger classes in their war files). Each application's own classloader will not find the class in the war file, so they will defer to their parent classloader, which is probably the shared, container-wide classloader. The parent classloader will load the Logger class and both applications will then be sharing the same Logger class.
Servlets in the same container will share some resources. I think it should be possible to deploy the same web application twice in the same container provided that you give each a different name and they don't collide on a particular resource. This would theoretically be the same as deploying two different servlets which just happen to have the same implementation, which we do all the time.
Some shared resources, off the top of my head (and I'm not an expert so don't quote any of this!):
- Libraries (jars) in tomcat/common/lib (Tomcat 5) or tomcat/lib (Tomcat 6).
- Settings in the global server.xml, web.xml, tomcat-users.xml
- OS provided things, such as stdin/stdout/stderr, network sockets, devices, files, etc.
- The logging system.
- Java system properties (System.getProperty(), System.setProperty())
- I suspect... static variables? I'm not sure if the ClassLoader design would prevent this or not.
- Memory. This is the most common problem: one servlet can deny others availability by consuming all memory.
- CPU - especially with multi-threaded apps. On the HotSpot JVM, each Java thread is actually an OS-level thread, which are expensive and you don't want more than a few thousand of them.
Doubtless there are more.
Many of these things are protected by a security manager, if you're using one.
I believe the isolation is in the class loader. Even if two applications use the same class name and package, their class loader will load the one deployed with the application.