Imagine a bacon-wrapped Ferrari. Still not better than our free technical reports.
See all our reports

Do You Really Get Classloaders?

Classloader Hierarchy

Whenever a new JVM is started the bootstrap classloader is responsible to load key Java classes (from java.lang package) and other runtime classes to the memory first. The bootstrap classloader is a parent of all other classloaders. Consequently, it is the only one without a parent.

Next comes the extension classloader. It has the bootstrap classloader as parent and is responsible for loading classes from all .jar files kept in the java.ext.dirs path–these are available regardless of the JVM’s classpath.

The third and most important classloader from a developer’s perspective is the system classpath classloader, which is an immediate child of the extension classloader. It loads classes from directories and jar files specified by the CLASSPATH environment variable, java.class.path system property or -classpath command line option.

classloader hierarchy: system classpath classloader, extension classloader, boostrap classloader

Note that the classloader hierarchy is not an inheritance hierarchy, but a delegation hierarchy. Most classloaders delegate finding classes and resources to their parent before searching their own classpath. If the parent classloader cannot find a class or resource, only then does the classloader attempt to find them locally. In effect, a classloader is responsible for loading only the classes not available to the parent; classes loaded by a classloader higher in the hierarchy cannot refer to classes available lower in the hierarchy.

The classloader delegation behavior is motivated by the need to avoid loading the same class several times. Back in 1995, the chief application of the Java platform was thought to be web applets living in the client (browser). As connections at that time were slow, it was important to load the application lazily over the network. Classloaders enabled this behavior by abstracting away how each class was loaded. All the bells and whistles came later.

However, history has shown that Java is much more useful on the server side, and in Java EE, the order of the lookups is often reversed: a classloader may try to find classes locally before going to the parent.

Java EE delegation model

Here’s a typical view of an application container’s classloaders hierarchy: there is a classloader of the container itself, every EAR module has its own classloader and every WAR has its own classloader.

Jave EE delegation model, application classloaders hierarchy

The Java Servlet specification recommends that a web module’s classloader look in the local classloader before delegating to its parent–the parent classloader is only asked for resources and classes not found in the module.

In some application containers this recommendation is followed, but in others the web module’s classloader is configured to follow the same delegation model as other classloaders–so it is advisable to consult the documentation of the application container that you use.

The reason for reversing the ordering between local and delegated lookups is that application containers ship with lots of libraries with their own release cycles that might not fit application developers. The classical example is the log4j library–often one version of it is shipped with the container and different versions bundled with applications.

“The reversed behavior of web module classloader has caused more problems with classloaders than anything else… ever.”
     - JEVGENI KABANOV

Now, let’s take a look at several common classloading problems that we might encounter and provide possible solutions.

Your time is too valuable to sit around waiting for your code to redeploy. Seriously, imagine how much more you could accomplish if you choose to Eliminate Redeploys from your daily routine!


DOWNLOAD THE PDF

  • Sivakumar Kailasam

    Insightful. Great report. Wish you guys would make more such posts.

  • arhan

    Thanks! We will come up with more posts for sure! You might want to check out the Scala adoption guide and Continuous Delivery report released in the same style

  • http://www.facebook.com/hotarugirl Nikki Tomoe

    A fantastic read; well written and easy to understand.
    Classloader problems are like a baptism of fire for Java programmers, it’s nice to have someone explain their fickle nature in a well-presented manner.

  • sandeepbh

    Some developers get confused with ClassNotFoundException which is different from NoClassDefFoundError. This article can be used as reference for the difference between the two. some readers who are new to class loader stuff may want to see:
    various types class loaders

  • mnkartik

    Awesome article about classloaders.

  • george mournos

    I dont want to argue about details but maybe it is better to find the code location from the ProtectionDomain and not by casting to URLClassloader. The code (except from the basic java classes which are loaded by the primordial classloader) will always be loaded in a protection domain, containing the certificates and the code locations. But the classloader might not extend URLClassloader, although this is the common case…