Java Class Loader – A Class apart
Posted On October 3, 2007 by GB Shah filed under Java
Java Class Loader – A Class apart
Class loaders have always been the key component of the Java, loading classes into the JVM at runtime. Class loaders fetch classes into the JVM, so they constitute the first line of defense in the JVM Sandbox, filtering malicious code, guarding trusted libraries, and setting up protection domains. Further, the J2EE architecture makes uses of the class loaders to the fullest. Almost every component of J2EE is the dynamically loaded by the application server. Understanding of such a vital component, the class loader, of Java is not so common among developers and often neglected as an advanced topic.
In this article we look through the java.lang.Class, class literals, class loaders – their hierarchy and delegation model.

JVM creates an instance of java.lang.Class for every data type loaded into memory. The instance of this java.lang.Class is also stored on heap like any other object. Every object in Java contains a reference to this Class object of its data type. The getClass() method can be used to obtain the associated Class object. The getClass() method is inherited from the java.lang.Object hence available in every class. For Example,
| For java.lang.String type, |
Java provides a unique type of literal called the class literal. The class literal is associated with every data type of java. The class literal is the Class object of the data type which is the same as the object returned by getClass().
| For primitive int, |
The java.lang.Class is the cornerstone for Java Reflection API. This class is used for the dynamic loading of classes in java; a method primarily employed in all J2EE compliant application servers. The most common API used for dynamically loading classes is the Class.forName(), which loads the class specified by its parameter and returns the reference to the java.lang.Class object. The Class.forName() is another way of obtaining reference to the Class object for any data type.
| For java.lang.String type, |
The Class object associated with the data type can be used create objects of the data type; using Class.newInstance() or java.lang.reflect.Constructor API. For more details, please refer to the documentation/articles related to java.lang.Class.
CLASS LOADER
Now that we know java.lang.Class, it’s easy to comprehend the class loader of Java, which is a type of java.lang.Classloader (or its sub types).
The purpose of a class loader is to load the byte codes in “.class” file, and build the java.lang.Class object corresponding to the loaded type on JVM heap memory.
The java.lang.Class object is used to create objects requested by the programs.

Java has hierarchy of class loaders linked in a chain of parent-child relationship. Every class loader in Java, except the bootstrap class loader, has a parent class loader. At top of the parent-child chain is the bootstrap class loader.
Most java programs have at least 3 class loaders active behind the scenes. They are as follows

Bootstrap or Primordial Class loader: Class loader is responsible for loading only the core Java API (e.g. classes files from rt.jar). Since the core classes are required to bootstrap any Java program the class loader is called bootstrap class loader. This is root of all the class loader hierarchy in a java application.
Extension Class loader: Class loader responsible for loading classes from the Java extension directory (i.e. classes or jars in jre/lib/ext of the java installation directory). This class loader is responsible for loading the “installed extensions”. Bootstrap class loader is the parent of this class loader.
System class loader or Application class loader: Class loader responsible for loading classes from the java class path (i.e. class directories or jars present in CLASSPATH environment variable of the Operating System). Extension class loader is the parent of this class loader. This class loader is by default the parent of all the custom/user defined class loaders in a java application.
There are also other class loaders like the network class loaders used in Applets and RMI for loading classes across the network. Also, J2EE compliant application severs have more class loaders in the hierarchy like web-app class loader, EJB class loaders etc. Subsequent sections of this document delve into BEA Weblogic class loader hierarchy.
The class loader that loaded a particular class can be obtained using getClassLoader() method on the Class object. For the standard Java API and primitive types, this method returns null, which represents the bootstrap class loader.
| System.out.println(int.class.getClassLoader()); //prints null System.out.println(String.class.getClassLoader()); //prints null // prints sun.misc.Launcher$ExtClassLoader@a9c85c which is the // prints sun.misc.Launcher$AppClassLoader@133056f which is the |
In J2SE 1.5, the system class loader is the class sun.misc.Launcher.AppClassLoader and the extension class loader is the class sun.misc.Launcher.ExtClassLoader.
CLASS LOADER DELEGATION MODEL
Before a particular class loader attempts to load a type in its custom way, by default it delegates the job to its parent –asking the parent to try to load the type. The parent, in turn, asks its parent to load the type. The delegation process continues all the way to the bootstrap class loader, which is the last class loader in the delegation chain. If a class loader’s parent class loader loads the reference type, the class loader returns the loaded type. Otherwise, the class loader attempts to load the type itself. This process is referred to as parent delegation model.
Let’s consider the following example to understand the parent-delegation model.
| class Door{} |
In the main method, a String object is created which implies that the java.lang.String class must be loaded prior to this operation. The request of loading the String class is given to the class loader that loaded the class Car, which is the system class loader (since the Car class has to be in the CLASSPATH and as mentioned earlier, system class loader is responsible for loading classes from the CLASSPATH).
As mentioned above, every class loader by default requests its parent to load the class prior to finding/loading the class on its own. System class loader requests the Extension class loader to load the java.lang.String class. The Extension class loader requests its parent the Bootstrap class loader to do the same. The Bootstrap class loader is the root of the delegation hierarchy, tries to load the java.lang.String. Since java.lang.String is present in the standard Java API (rt.jar), the bootstrap class loader loads the String.class file; and returns the Class object created, from the byte codes, to the extension class loader. Extension class loader in turn returns the same to the System class loader which returns it to the class Car, where it is used to create the String object.

Every class is loaded only once by each “class loader hierarchy” and is placed in a class cache. Subsequent requests for the same class result in the cached Class object being returned; thus avoiding the whole delegation process to load the same class.
Now lets consider the second statement of the main method in the class Car, which requests for Door.class file. Again the System class loader is asked to load the class, which delegates to its parent - the Extension class loader, which in turn delegates the request to its parent - the Bootstrap class loader. Now the Bootstrap class loader tries to loader the Door.class, since class Door is not part of the standard Java API, it fails to load the class and returns back to the extension class loader. The Extension class loader also fails to load the class and returns back to the System class loader. Now the System class loader finds the class in the CLASSPATH loads the Door.class file and returns the Class object corresponding to it. The Class object is made part of the class cache too, so the further requests do not require the repetition of the whole class loading process.
An important point to remember is that the class requested must be found by the class loader (or the parent class loaders) that loaded the requesting class. For example, if the class Car was in the jre/lib/ext directory and class Door was in the CLASSPATH, then a ClassNotFoundException would be thrown indicating that the class Door is not found. In this case the Extension class loader would have loaded the class Car; so the Extension class loader will request only the Bootstrap class loader for the class Door and never ask System class loader to load it, as specified by the parent-delegation model.
Class loading related errors
The following errors are the common errors related to class loading
Ø ClassNotFoundException
This exception occurs when the class loaders fail to find the requested class. Such an exception occurs only for dynamically loaded classes. This means that a class that is required only at runtime could not be found by the class loaders. The fix to this issue is to understand the class loaders involved; the relation between class loader loading the requesting class and the class loader loading the requested class. Please refer to the previous section for more details on the delegation model.
Ø NoClassDefFoundError
This exception occurs when a class statically linked by the compiler is not found during runtime. This means that the class is necessary for compilation, so the class was present during compilation, but the class cannot be found during runtime by the class loaders. A look a runtime class path and class loaders can solve the issue.
Ø ClassCastException
This exception occurs in two cases
1. When try casting between two different incompatible class types. This issue is easy to fix.
2. Another scenario is when the class accesses an object of the same class loaded by another class loader hierarchy. Consider the following diagram; here the ArrayList consisting of Car objects is used by the class ABC. A class cast exception occurs when the object in the ArrayList is converted to type Car.

This can be surprising to a lot of developers, since object contained in the list is of type Car the exception should not occur. Solving the issue requires understanding of class loaders. The error occurs because the objects in the ArrayList have been created from the class Car loaded by User Defined Class loader 1 (UDCL1) while the Car reference in ABC is loaded from the User Defined Class Loader 2 (UDCL2). Since there is no relation between UDCL1 and UDCL2 (except they have common parent); the objects loaded by UDCL1 must not access the objects loaded by UDCL2, even though it’s the same class loaded by two different class loaders. However errors occur when the same class is present in two different class paths. Such errors are not so uncommon in application servers and are quite difficult to debug and fix. An understanding of the application server class loader hierarchy will help fixing the issue.
CONCLUSION
These class-loading basics are necessary for every java/j2ee developer better understand the working of the Java environment.
To reiterate again
Ø Every data type in java is represented by an instance of the java.lang.Class object.
Ø Class loader loads the byte codes from the “.class” file and creates a Class object
Ø Most java program at minimum has 3 class loaders, Bootstrap, Extension and System class loaders.
Ø Every class loader delegates the class load requests to its parent before trying to load the class on its own.
