Tuesday, April 10, 2007

Java EE Class Loading Architectures

At JavaOne Conference, Ernie Svehla gave a talk about JEE class loading. Ernie explains that classes can be loaded implicitly as a result of a reference, instantiation or inheritance or explicitly by for example a call to Class.forName(). A class is defined by its name and its associated class loaded. There are 2 key class loading concepts.

1. Isolation: ensures that classes used by one application cannot be seen by another

2. Delegation: defer a request to load the class to a parent before attempting to load the class myself.

Core class loaders include the bootstrap which load the java.lang.* files from rt.jar, the extension which loads jar files contained in jre/lib/ext, and system or application which loads classes on the class path and shared jars. This creates a hierarchy of class loaders. A user class calls its class loader which delegates to its parent (system). If system cannot find the class, it delegates to its parents and so on (system->extension->bootstrap). If class is still not found, the user class loader then tries to load the class or throws an exception.

Different JEE app servers have different hierarchies and algorithms for loading classes. EJBs, WARS, WEB-INF, manifest, etc. Depending on where classes are, an app might need to be restarted or it can simply be a hot deploy.

Ernie then recommends some packaging guidelines. He recommends leveraging EARs. They should be self contained, include all dependent jars but minimize dependency on core environment like jdbc jars. He recommends packaging common jars needed by wars with ejb jars and to allow wars to be self contained.

Next Ernie covers different application servers and explains how each implements class loading. After that, Ernie gives some examples of the most common errors due to class loading.

1. ClassNotFoundException: Reference to class is to high in the hierarchy or using incorrect string in ClassLoader.loadClass(className)

2. NoClassDefFound: Class existed at compile time, but is no longer available (.class file is deleted or not copied properly in build)

3. ClassCastException: Class loaded by 2 different class loaders (WAR and EJB) or attempting to cast an object to a non compatible type

4. ClassCirculatoryError: Circulatory dependency or a class and one of its dependents are both dependent on a third class and different class loaders are used to load that 3rd class.

5. Class path issues: improper url specification when using URLClassLoader. url ending with slash references a directory. If no slash, it is referring to a jar file with the name of directory.

6. Class visibility issues: A class cannot be seen due to the class loader hierarchy.

Then Ernie explains how to create a custom class loader by overriding the loadClass() method associated with java.lang.ClassLoader.

Ernie wraps up reminding us that we need to understand how java class loading works; we need to understand how specific JEE servers works and we need to pay attention to how classes are packaged.

This presentation is available on InfoQ at http://www.infoq.com/presentations/java-classloading-architectures-ernie-svehla