Java Class Loading…

Nipun Thathsara
4 min readApr 15, 2020

--

Loading is the process of finding the binary representation of a class or interface type with a particular name and creating a class or interface from that binary representation.

Java class loading is basically reading the *.class files from a source directory(directory location in the file system or in a network) and loading them in to the JVM/memory. From an Operating System’s perspective, compiled class file stored in the file system is binary. If JVM is to execute the logic written in byte code, it should first read these files in to the memory.

java.net.URLClassLoader.java

Java class loading happens only on-demand, dynamically. It doesn’t load all the class files in your classpath at the startup. Rather, only when one’s referred. This helps optimizing the memory usage. And once loaded, it will not be unloaded. That improves performance but indeed at the cost of memory. Big application with many classes could ultimately acquire large amount of memory, given that in the long run most of its classes will be utilized.

Class Loaders

  1. Bootstrap class loader
  2. Extension class loader
  3. Application/System class loader

Bootstrap(Primordial) Class Loader

Resides on top of the chain. Parent of them all. Still, you wouldn’t see that java.lang.ClassLoader is extended by Bootstrap class loader. Because it’s a native class(written in C mostly) in the JVM. Implementation of the this class loader differs as per the underlying O/S’s architecture (It’s the platform dependent JVM which makes the Java byte code ‘compile once, run anywhere’). Given all the other class loaders themselves are Java classes, there has to be a loader to load them at the first place. Bootstrap loader does that.Responsible of loading the core libraries in the $JAVA_HOME/jre/lib/* directory such as rt.jar.

nipun@nipunt:/usr/lib/jvm/jdk1.8.0_151/jre/lib$ grep -ir . "ClassLoader.class"
Binary file rt.jar matches
nipun@nipunt:/usr/lib/jvm/jdk1.8.0_151/jre/lib$ grep -ir . "Launcher.class"
Binary file rt.jar matches

Extension Class Loader

Is responsible of loading classes from extension directories such as $JAVA_HOME/lib/ext directory. Implemented inside the sun.misc.Launcheras Launcher$ExtClassLoader. This loader reads the java.ext.dirs system property to get the locations to be queried. Therefore, any directory that is listed inside that mentioned system property will be queried for classes by the ExtClassLoader.

sun.misc.Launcher$ExtClassLoader.java

Application/System Class Loader

This class loader is used to launch the application. Reads the classes from the application’s class path (java.class.path system property). You can also define it by passing -cp or -classpath arguments to the JVM.

sun.misc.Launcher$AppClassLoader.java

Apart from those class loaders, you can also write your own class loader. May be in another post.

Principles of Class Loading

  1. Visibility :
    Classes that are loaded by a parent class loader, are visible to child class loaders. Whereas parents can’t see the classes loaded by its child loaders.
    If class C is loaded by AppClassCloader and C2 by ExtClassLoader, then ExtClassLoader is unaware of C2. But AppClassLoader is aware of both C and C2.
  2. Uniqueness :
    A class should not be re-loaded by a child loader, if it’s already been loaded by a parent loader. (But this doesn’t mean that you can’t load the same class twice. With two custom loaders which do not inherit one another might load the same class into two different name spaces.)
  3. Parent Delegation :
    Java class loaders have a hierarchy. A child class loader never tries to load the class by itself. It should check if it’s been already loaded. If so, no need of loading again.
    Otherwise, it delegates the request to its immediate parent. This happens recursively until the request hits the Bootstrap loader. As it’s the parent of them all, now the Bootstrap loader gives a try to load the class. If it couldn’t, it delegates the request to the Extension loader. Likewise, the delegation effort is now propagated down the hierarchy. If, even the bottom most loader is unable to load the class, then we throw a ClassNotFound exception.
Delegation

Below sample is to demonstrate some some class loadings.

Foo.java

Results of the above snippet would be as follows.

Hello World!
java.ext.dirs : /usr/lib/jvm/jdk1.8.0_151/jre/lib/ext:/usr/java/packages/lib/ext
com.sun.crypto.provider.AESKeyGenerator : sun.misc.Launcher$ExtClassLoader@5cad8086
Foo : sun.misc.Launcher$AppClassLoader@18b4aac2
String array : null
ArrayList : null

System argument java.ext.dirs set to jre/lib/ext and usr/packages/lib/ext directories. Therefore, whatever the classes that are there, will be loaded by the Extension Class Loader. Such as AESKeyGenerator. And this application’s Foo class is loaded by the Application Class Loader. Arrays are loaded by Bootstrap Class Loader. That’s why it was printed as null.

Leave a comment if you find anything should be corrected or added.

Cheers.

References

[1] https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html

[2] https://www.baeldung.com/java-classloaders

[3] https://github.com/openjdk/jdk

[4] https://medium.com/platform-engineer/understanding-jvm-architecture-22c0ddf09722

--

--