Understanding Class Loading
1. Understanding Class Loader Hierarchy
| Loader | Loads |
| Bootstrap | Core JDK (java.base) |
| Platform (Java 9+) | JDK platform modules |
| Application (System) | Classpath / module-path |
| Custom | Plugins, web apps, isolation |
2. Using Bootstrap Class Loader
| Aspect | Detail |
| Implementation | Native (C++) |
| Parent | None — represented as null |
| Loaded modules | java.base and a few core |
| Aspect | Detail |
| Replaces | Old Extension class loader |
| Access | ClassLoader.getPlatformClassLoader() |
| Loads | Non-base JDK platform modules |
4. Using Application Class Loader
| Aspect | Detail |
| Access | ClassLoader.getSystemClassLoader() |
| Parent | Platform loader |
| Loads | App classpath / module-path |
5. Understanding Parent Delegation Model
| Step | Action |
| 1 | Check own cache |
| 2 | Delegate to parent |
| 3 | Parent recurses to bootstrap |
| 4 | If unresolved, this loader's findClass tries |
Note: Web containers (Tomcat) deliberately invert delegation for WEB-INF/classes to isolate web apps.
6. Creating Custom Class Loaders
Example: Custom loader
public class MemoryClassLoader extends ClassLoader {
private final Map<String, byte[]> classes;
public MemoryClassLoader(ClassLoader parent, Map<String, byte[]> classes) {
super(parent); this.classes = classes;
}
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] b = classes.get(name);
if (b == null) throw new ClassNotFoundException(name);
return defineClass(name, b, 0, b.length);
}
}
| Override | Use |
findClass | Standard delegation |
loadClass | Custom delegation order |
7. Loading Classes Dynamically (Class.forName)
| Form | Behavior |
Class.forName("p.C") | Initializes class |
Class.forName(name, init, loader) | Choose loader and init flag |
loader.loadClass(name) | Loads but does not initialize |
8. Understanding Class Initialization
| Phase | Action |
| Loading | Bytes → Class object |
| Linking | Verify, prepare, resolve |
| Initialization | Run static initializers and field assignments |
| Trigger | First active use (new, static field/method, reflection forName(init=true)) |
9. Using Context Class Loader
| API | Use |
Thread.currentThread().getContextClassLoader() | Get |
setContextClassLoader(cl) | Set |
| Use case | Frameworks discovering app classes from JDK code (ServiceLoader, JNDI) |
10. Understanding Class Loader Isolation
| Aspect | Detail |
| Class identity | Class = (loader, fully qualified name) |
| Same class, different loaders | Considered DIFFERENT types — ClassCastException |
| Use | Plugin sandboxing, hot reload |
11. Resolving Class Loading Issues
| Error | Cause / Fix |
| ClassNotFoundException | Missing on classpath; reflective lookup |
| NoClassDefFoundError | Class loaded once but missing now (e.g., transitive dep) |
| LinkageError | Same class loaded by two incompatible loaders |
| UnsupportedClassVersionError | Class compiled for newer JVM |
| Diagnose | -verbose:class, jcmd VM.class_hierarchy |