ClassLoader is a special component in the JVM responsible for loading the bytecode of classes into memory when they are first used. It allows classes to be dynamically loaded from various sources (file system, network, archive, etc.).
Types of class loaders:
jre/lib/ext.ClassLoader implements delegation: it first tries to load the class from the parent loader (parent-first), only if it fails does it look for it itself.
Class isolation: Each class loader creates its own "visibility area" for classes. Two classes with the same name loaded by different loaders are considered different types within the JVM.
Example of creating a custom loader:
class MyClassLoader extends ClassLoader { @Override protected Class<?> findClass(String name) throws ClassNotFoundException { // Your code for searching and loading the class bytecode return super.findClass(name); } }
Can two classes with the same name loaded by different loaders be considered the same class within the JVM?
Answer: No! The JVM considers a class unique based on the tuple (fully qualified name of the class, class loader). Therefore, the same classes loaded by different loaders are considered different.
Story
In an enterprise application with a plug-in architecture, plugins were loaded by separate class loaders. As a result, attempting to transfer an object of the interface type (PluginInterface) between the main application and the plugin caused ClassCastException because the same interface was loaded by different loaders.
Story
When using a custom class loader, delegation to the parent loader was not implemented. This led to the reloading of standard library classes, causing strange ClassCastException and LinkageError errors.
Story
In a large Java EE server, different applications were loading their own versions of the same library. Negligence in configuring the loader chain led to class overlaps between applications, which once caused a massive memory leak and failures due to version conflicts.