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).
java -cp MyJar.jar:lib/* com.somepackage.subpackage.Main // for linux
java -cp MyJar.jar;lib/* com.somepackage.subpackage.Main // for windows
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.