In Java, classes are loaded into memory by special objects called class loaders. Each class loader creates its own namespace for classes.
Types of class loaders:
$JAVA_HOME/lib/ext.Features:
Can multiple versions of the same class be loaded into the JVM process, and how can this be done?
Answer: Yes, it is possible if different class loaders are used. Classes with the same FQDN loaded by different loaders are considered different types for the JVM.
Example:
ClassLoader loader1 = new URLClassLoader(new URL[]{...}); ClassLoader loader2 = new URLClassLoader(new URL[]{...}); Class clazz1 = loader1.loadClass("com.example.MyClass"); Class clazz2 = loader2.loadClass("com.example.MyClass"); System.out.println(clazz1 == clazz2); // false
Story
In a large server system, plugins were used, each connected via a separate custom classloader. Plugins exchanged objects through a common interface, also loaded by its classloader. A ClassCastException occurred during type casting because the 'PluginApi' interface from the plugin's classloader and the main system was considered different types.
Story
An attempt to "hot" reload a servlet through a custom classloader led to memory leaks — the old class was not unloaded from memory because a reference remained in static variables. As a result, PermGen quickly filled up.
Story
A product with support for dynamic module loading implicitly used the system class loader, and developers accidentally replaced its parent, losing access to basic classes (e.g., from JDK). This manifested in crashes when a new module could not load standard Java classes, such as
java.sql.Driver.