Class loaders

29 January 2014

In Java, every class needs to be loaded before it can be used.

The class loader (which is part of JVM) is responsible for finding and loading the java classes.

A class loading is made once, at its first use.

Classes are uniquely identified by their fully qualified name and by the class loader which loaded them.

Popular exceptions caused by the class loading: ClassNotFoundException, ClassCastException, NoClassDefFoundError.


Default class loaders hierarchy of the JVM
There are 3 class loaders used when the JVM is started:
  1. Bootstrap class loader
  2. Extensions class loader
  3. System class loader
Bootstrap class loader
Extensions class loader
System class loader
Parent delegation model

Each class loader has a "parent" class loader (besides the bootstrap class loader which is the root). When creating a class loader, if there isn't specified its parent, the system class loader will become its parent class loader.

When loading a class, the ClassLoader does the next actions:
  1. If a class has already been loaded, it returns it (from cache)
  2. Otherwise, it delegates the search for the new class to the parent class loader (to avoid loading the same class multiple times which causes ClassCastException)
  3. If the parent class loader does not find the class, loadClass method calls findClass method in order to find and load the class

Role of the Thread context ClassLoader and how it can be used

Let's take some examples.

First example. Logging

Bootstrap class loader loads the java libraries (located in jre/lib) =>java.util.logging.Logger is loaded by Bootstrap class loader.
This logger can use internationalization.

The resource bundle to be used is loaded by the System class loader.
The Bootstrap class loader is not able to load the resource bundle, so the Logger class needs to use the class loader of the application; more precisely, the class loader of the current thread: ClassLoader cl = Thread.currentThread().getContextClassLoader();

A second example. Spring

Spring is used for managing beans. Let's say that Spring library is kept under tomcat/lib. Those classes are loaded by the common tomcat class loader.

For each web application in webapp folder, a new class loader is created. This class loader loads the classes in WEB-INF/classes and WEB-INF/lib.
=> Normally, Spring cannot see those classes because they were loaded by a different class loader.

In order to solve those issues, Java introduced the Thread.currentThread().getContextClassLoader() which can get the application's class loader and use it for loading the classes in WEB-INF/classes or WEB-INF/lib.


Loading, Linking and Initialization of classes

Java Language Specification, Execution chapter is one of the best materials to read for this subject: https://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html


References: