How does classloading works in a Java Application(J2SE)
Class loading is one of the most important aspects of Java and most of the times its abstracted away from us when we use IDEs and dependency management tools like Maven. For most of the part its ok until one fine day you stumble upon something a NoClassDefFoundError and have to bite the bullet to figure out How does actually class loading works in Java?
There are multiple class loader in Java Runtime and for most of the part they use a delegation model (we will cover it in a moment). The figure below demonstrated the typical Class loading model in a J2SE application(Note: Things are a bit different in J2EE world).
- Bootstrap class loader: This is the top most class loader, which means that it has no parent, and is responsible for loading the default classes that comes bundled with Java.
Example: You must have used System.out.println(“Hello World”); sometime in your code but ever wondered that where the System class is located?
The default Java runtime classes are located in %JAVA_HOME%/jre1.8.0_XX/lib/rt.jar and are loaded by the bootstrap classes.
TIP: rt.jar file is just like a zip file and can be cracked open by a utility like WinRAR, do try opening the file now to peek into all the available classes.
- Application Class Loader: You can always specify the classpath while running a class like so
java -cp MyJar.jar:lib/* com.somepackage.subpackage.Main // for linux java -cp MyJar.jar;lib/* com.somepackage.subpackage.Main // for windows
It’s easy enough to understand and it loads all the class(es) present in the specified path.
The Delegation Model :
So what happens when you reference a class in your code and the JVM has to load that class for the first time?
When your application requires a Class file it makes a request to the Application Class Loader, if it has the class in the cache it returns the class otherwise it sends the request to the Extension class loader which follows the same process.
Travelling up the chain if the request reaches the Bootstrap class loader and it also does not have the class cached, it will try to load it, and if the class is loaded it will cache it otherwise it will throw a NoClassDefFoundError Exception which is caught by the Extension class loader.
Now the Extension class loader will try to load the class ,if successful in loading it will cache it or else will throw a NoClassDefFoundError, which will be caught in by the Application class loader.
Finally the Application class loader will try to the load the class and will cache it if it succeeds or else it will return a NoClassDefFoundError to the application.
Please feel free to comment on this post if you have a question or a suggestion.