# Catalina Class Loader Hierarchy

[Introduction] [Overview] [Process] [Notes]

### Introduction

Like many server applications, Catalina installs a variety of class loaders (that is, classes that extend `java.lang.ClassLoader`) to allow different portions of the container, and the web applications running on the container, to have access to different repositories of available classes and resources. This mechanism is used to provide the functionality defined in the Servlet API Specification, version 2.3 (public draft 1) -- in particular sections 9.4 and 9.6.

The remainder of this document provides an overview diagram of the parent - child relationships between each class loader that is created, more detailed information about the content and use of each class loader, and some additional relevant notes.

### Overview Diagram

In a Java2 environment, class loaders are arranged in a parentage tree. Normally, when a class loader is asked to load a class (or get a resource), it delegates the request upwards first, and only searches its local repositories if the parent class loader(s) cannot find the requested class or resource. The model for web applications differs slightly from this, as discussed further below.

The class loaders that Catalina uses are organized as follows, where the parent class loader is above the child class loaders:

                          Bootstrap
                              |
                           System
                              |
                           Common
                          /      \
                     Catalina   Shared
                               /     \
                           Webapp1  Webapp2 ...
                             /          /
                          Jasper1   Jasper2

The usage of and repositories contained in each class loader are described further below:

- Bootstrap - This class loader contains the basic runtime classes provided by the Java Virtual Machine, such as the `java.*` classes. Depending on how your particular JVM is organized, this may actually be more than one class loader, or may not exist at all. It is generally not referenced directly.
- System - This class loader is initialized from the contents of the `CLASSPATH` environment variable, and contains classes that must be visible to both the Catalina internal classes and to web applications. The standard Catalina startup scripts assemble the following repositories for the system class path:
  - `$CATALINA_HOME/bin/bootstrap.jar` - The Bootstrap class that is used to initialize the Catalina server, and the class loader implementation classes it depends on.
  - `$JAVA_HOME/lib/tools.jar` - The Javac compiler used to compile the servlets generated from JSP pages (if present on your system).
- Common - This class loader is initialized to include all unpacked classes in the `$CATALINA_HOME/common/classes` directory (if it exists), and all JAR files in the `$CATALINA_HOME/common/lib` directory (if it exists). The latter group normally includes the following:
  - `jndi.jar` - The Java Naming and Directory Service API classes (loaded only if not already included in the JDK, as they are with JDK 1.3).
  - `naming.jar` - The JNDI implementation used by Tomcat 4 itself.
  - `servlet.jar` - The servlet and JSP API classes.
- Catalina - This class loader is initialized to include all unpacked classes in the `$CATALINA_HOME/server/classes` directory (if it exists), and all JAR files in the `$CATALINA_HOME/server/lib` directory (if it exists). Because these classes are loaded from a separate class loader, which is not visible to the Webapp class loader, they are not visible to web applications.
- Shared - This class loader is initialized to include all unpacked classes in the `$CATALINA_HOME/classes` directory (if it exists), and all JAR files in the `$CATALINA_HOME/lib` directory (if it exists). All of the classes in these repositories will be visible to all web applications, so they may be used to share information between web apps. (NOTE - this behavior is specific to Tomcat 4.0, and will not necessarily be portable to other containers.)
- WebappX - A class loader is created for each web application that is installed in Catalina, and initialized to include the `WEB-INF/classes` directory (if it exists), plus all JAR files in the `WEB-INF/lib` directory, for this web app. Because of the parentage hierarchy, web applications can indirectly see (and therefore load classes from) the Shared, Common, System, and Bootstrap class loaders, but not from the Catalina or JasperX class loaders.
- JasperX - If and only if a web application utilizes Jasper to compile and execute JSP pages, an additional class loader is created for each web application. It is initialized to include all JAR files in the `$CATALINA_HOME/jasper` directory, which normally includes the Jasper compiler classes and the XML parser that they require. Because the parent of this class loader is the WebappX class loader for this application, the JSP compiler can see all of the JavaBean and other classes that are part of this application, but the application classes cannot see anything loaded from here (and, in particular, will not have access to the XML parser loaded by this class loader.

As you can see from the above descriptions, the contents of any `CLASSPATH` environment variable already existing in your server is totally ignored. If you want to make a JAR file available to all web applications, you must place a copy of this file in the `$CATALINA_HOME/lib` directory so that it becomes part of the Shared class loader's repositories.

### Web Application Class Loading Process

When a servlet (or JSP page) within a web application references a class for the first time (either by using the `new` operator or by calling the `Class.forName()` method), the following processing occurs to locate and load the requested class:

1. The `loadClass()` method of the WebappX class loader is called to load the specified class.
2. If this class has been previously loaded by this class loader, the cached copy is returned again. This avoids having to do potentially expensive I/O every time a class is requested.
3. If the class to be loaded is a Java core class (`java.*`), it is loaded directly by the System class loader.
4. If Catalina is running under a security manager (which is normally the case), the class loading permissions in the policy file are checked. If the specified policies prohibit loading the named class, the class loader will log the violation attempt and return a `ClassNotFoundException`.
5. If this class loader's `delegate` property is set to `true` (which is not the default), we will ask our parent class loader to load this class before looking locally. This is the standard Java2 delegation model, but prevents a web application from overriding a class from the Shared class loader with its own copy from `WEB-INF/classes` or a JAR file in `WEB-INF/lib`.
6. The local repositories are searched next, starting with the `WEB-INF/classes` directory (if it exists), and then the JAR files in `WEB-INF/lib`.
7. If we still have not found the class, and did not delegate earlier, we delegate to our parent class loader (i.e. the Shared class loader, which will attempt to load the class itself or delegate upwards. This process continues until the class is found, or we have reached the top of the class loader hierarchy.
8. If the class has still not been found, `ClassNotFoundException` is thrown, as required by the Javadocs for a class loader.

A similar pattern is followed when you call `Class.getResource()` or `Class.getResourceAsStream()` to access resources that are co-resident with your classes.

### Miscellaneous Notes

#### Class Loader Information Exposed For Web Applications

Certain web application components (such as the Jasper JSP page compiler servlet, require additional information related to class loading to operate successfully. To avoid creating dependencies between the Jasper and Catalina code bases, this information is exposed as a set of servlet context attributes that are initialized when the web application is started. The following context attributes are created:

- org.apache.catalina.classloader - The Webapp class loader for this application (which will also be the class loader used to load the Jasper servlet itself).
- org.apache.catalina.jsp_classpath - A String representation of the directories and JAR files available in the webapp, shared, and system class loaders, with each repository separated by the appropriate path separator character for the platform this server is running on.

#### A Note On XML Parsers

Previously, the Jasper page compiler was loaded in the Shared class loader, along with the XML parser that it requires. This had the side effect of causing this XML parser to be visible to all web applications, through the inheritance hierarchy. However, this causes problems if the JAR files of the selected XML parser are sealed (as are the JAR files in the JAXP 1.1 reference implementation, for example) -- any attempt to load your own XML parser (such as Xerces) from `WEB-INF/lib` would cause "package sealing violation" errors to be thrown.

Now that the XML parser required by Jasper is loaded from the JasperX class loader, rather than the Shared class loader, this problem no longer occurs. However, any web application that relied on an XML parser being made available by Catalina will fail, because this is no longer true by default. If your web application requires an XML parser, you have three choices:

- Place the XML parser's JAR file(s) in the `WEB-INF/lib` directory of your web application.
- Move the XML parser JAR files from the "jasper" directory to the "lib" directory so that the parser is visible both to Jasper and to your web applications.
- Place the XML parser's JAR file(s) in the `$CATALINA_HOME/lib` directory so that they are available to all web applications. Note that this is likely to introduce "package sealing violation" problems again, so this option is only practical if your applications do not require JSP pages.

#### Additional Information

For more information about class loaders in general, see the Java Language Specification, and the Javadocs for the following classes:

- `java.lang.ClassLoader`
- `java.net.URLClassLoader`

The implementation class for all Catalina internal class loaders is `StandardClassLoader`. Required and available optional packages are described using the `Extension` class. For more information, see the source code and/or Javadocs for the following classes:

- `org.apache.catalina.loader.StandardClassLoader`
- `org.apache.catalina.loader.Extension`

$Id: classloaders.html,v 1.6 2001/03/27 01:54:19 craigmcc Exp $