by Steven J. Owens (unless otherwise attributed)
Here, I'm going to try to talk about:
In an earlier section I mentioned that the special and specific meaning of the phrase web application in the java world. This was first set out in the Servlet Spec 2.3, essentially a way of drawing a line around all the stuff that makes up a given application - all the related elements and pieces - and calling it a web application.
The phrase "web application" is usually used in two senses, either in reference to the running application in the servlet engine, or in reference to the collection of directories-and-files that make up the application. The running application sense is useful when you're talking about variable scope and classloaders, and is often called the Servlet Context. The directories-and-files sense is useful when you're talking about putting together the pieces that the servlet engine needs to have in order to create the running application sense.
The directories-and-files sense is about packaging up the various pieces of a set of related web pages, binary assets, JSPs, servlets, class files, resources and configuration. These are usually copied to somewhere under the servlet engine's directory structure. Strictly speaking, they don't have to be copied to under the engine's directory structure, the engine could do whatever it wanted with them - it could stick them all in a database as BLOBs. But practically speaking, pretty much all of the servlet engines I know about just store them as directories and files.
The concept of a WAR file (Web Application Archive) was also introduced, which is more or less a web application in a specialized tar file format, along with some things like manifests and meta files. This makes it even more packaged and easy to ship around, deploy and undeploy etc.
I haven't personally worked with WAR files much at all, so I can't say much about them, except to observe that, strictly speaking, the spec doesn't say how the engine has to handle the WAR file. Practically speaking, just about every servlet engine expands the WAR file into a set of files and directories, under the servlet engine's hierarchy. Of course, you still can't mess with that expanded WAR, because the next deployment will overwrite it.
One implication of this is that the servlet spec doesn't really define anything about configuration persistence. There are some places to stick configuration information - inside web.xml, for example - but if your app needs to save config data somewhere where it will persist across engine restarts and the occasional WAR redeployment, you're going to have to go outside the spec to figure out where to store it. If you store it in a data file in the WAR, any changes will be lost when you redeploy it. So far, the only answer I've come up with is to either set up some sort of JNDI server to store your config data statically, or to put it in a database. That still leaves the question of setting up the database pool name in the web.xml. I may well be wrong, but so far I consider this one of the gotchas of the servlet spec.
The servlet engine runs all web applications inside the same JVM and therefore inside the same OS-level process. However, the servlet spec requires the servlet engine to run the webapps in a fairly isolated sense. The biggest part of this is the classloader. If you don't know much about classloaders in java, I highly recommend you go and read this really useful white paper:
Each webapp has its own classloader. This means, for example, that if you have a singleton pattern in a class under one webapp, the code in a second webapp can't get at it. Note that although singletons are incredibly handy for various specialized purposes, strictly speaking you shouldn't use them in webapps. Why not? Because the Servlet Spec leaves the servlet engine free to pull all sorts of shenanigans with classloading and session distribution and clustering. You can't count on a singleton really being a singleton, though in many cases it will be.
The webapp file hierarchy pretty much consists of the following:
appname/ appname/WEB-INF/ appname/WEB-INF/web.xml appname/WEB-INF/lib/ appname/WEB-INF/classes/
Any files under appname will be served by the servlet engine as if they were under a normal web server's htdocs directory. Any files under the WEB-INF subdirectory will be handled specially. For a start, WEB-INF and everything under it will not be served directly by tomcat. The web.xml file contains the webapp-specific configuation details. The WEB-INF/lib subdirectory is where you store any JAR files that your application especially needs. The WEB-INF/classes subdirectory is where you store any non-JARred class files for your application.
Some JAR files don't get stored under WEB-INF/lib. Any JAR file that needs to be shared across the servlet engine, for example. A JDBC driver JAR file is one example. Due to the way that JDBC connection pooling is usually implemented at the servlet engine level and then connections are provided to each webapp via JNDI, the JDBC driver JAR has to be shared across the entire servlet engine. Servlet engine wide JAR files go under the servlet engine, wherever that particular servlet engine dictates (in Tomcat it's in tomcat/common/lib).
While web.xml is where the webapp specific configuration details go, just as with JDBC drivers, some configuration details really are specific to the servlet engine. Where these go and how they're configured are specific to any servlet engine. With tomcat, for example, you have a tag set that defines the details for each webapp context, and it's called, appropriately enough, <CONTEXT>.