ProgrammingSenior Java Backend Developer

How does the class loading mechanism work in Java, what types of class loaders exist, and what potential problems can arise from their improper use?

Pass interviews with Hintsage AI assistant

Answer.

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:

  1. Bootstrap ClassLoader — loads the basic JDK classes (rt.jar, etc.).
  2. Extension ClassLoader — loads extensions from $JAVA_HOME/lib/ext.
  3. System (Application) ClassLoader — loads classes from the application's classpath.
  4. Custom ClassLoader — user-defined loaders for dynamic loading.

Features:

  • A class is considered unique within the combination (class loader, class name).
  • Two identical classes loaded by different loaders are considered different.
  • Class loaders form a hierarchy (parent-child).
  • Classes can be loaded from bytes (defineClass) — relevant for plugins/JSP, etc.

Trick question.

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

Examples of real errors due to ignorance of the nuances of this topic.


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.