When setting up a Java web application using Tomcat as an application server I often get confused about when libraries are available. Through some discussion on Stack Overflow,
The compile classpath is the classpath used to compile your Java source files (using javac -cp ...
, or your IDE). Every class referenced in the source file must be present in the compile classpath, else the compiler will complain that it can't find the class.
Once you have compiled the classes, you can run a program using them (using java -cp ...
). Obviously, the libraries on which your source code depends directly should be in the runtime classpath. But that's not all. If you depend directly on CoolLibrary.jar, and this library internally depends on Guava.jar, then Guava.jar must also be in the runtime classpath, although it was not needed when compiling.
Webapps are a bit special. The servlet specification specifies that the classpath used to execute the webapp is composed by the WEB-INF/classes directory of the deployed webapp, and of all the jars contained in WEB-INF/lib. All the webapps also have access to the native servlet and JSP jars, which are directly provided by Tomcat. In reality, Tomcat's internal classes (like the implementation classes of the servlet-api interfaces) are also available to the webapp, but relying on these classes is not a good idea, since it would tie your webapp to tomcat.
Talking of the runtime classpath, in the case of a webapp, is a bit of a simplification. In reality, every webapp's classes are loaded dynamically by a specific classloader by tomcat. And this webapp classloader is a child of the tomcat's classloader. So, in theory, you could place the webapp jars in Tomcat's classpath directly, but this would mean that all the webapps would share these libraries, and that you would have problems undeploying and redeploying webapps. The goal of having a specific classloader per webapp is to be able to have, in the same JVM, an app relying on Guava 11.0, and another one relying on Guava 12.0, for example.
For more information about tomcat classloaders, read the documentation.
in eclipse, you have the java build path
which include the libraries during compile time, and you have order and export
, which is for the runtime.
only the tomcat libraries available by default