All 15 Class Loading & Bytecode Verification questions
More in Class Loading & Bytecode Verification
Advertisement
Back to results for “Memory & Garbage Collection”
Java › Class Loading & Bytecode Verification

How would you implement a custom ClassLoader to load classes from a non-standard source, such as loading plugin JARs dynamically at runtime, and what challenges arise with class unloading?

Advanced

Answer

A custom ClassLoader extends ClassLoader (or URLClassLoader for JAR/URL-based loading) and overrides findClass() to define how to locate and read the raw bytecode from your custom source (a database, a plugin directory scanned at runtime, a network location), then calls defineClass() to convert those bytes into an actual Class object -- a major challenge is that a loaded class (and all its instances) can only be garbage collected once both the Class object itself AND the ClassLoader that loaded it become entirely unreferenced, meaning improperly discarding a plugin's ClassLoader reference (while still holding references to instances it created) causes a classloader leak, a notoriously tricky category of memory leak.
public class PluginClassLoader extends URLClassLoader {
    public PluginClassLoader(URL[] urls, ClassLoader parent) {
        super(urls, parent);
    }
}

// Dynamically load a plugin JAR at runtime
URL pluginUrl = new File("plugins/my-plugin.jar").toURI().toURL();
PluginClassLoader loader = new PluginClassLoader(new URL[]{pluginUrl}, Main.class.getClassLoader());
Class<?> pluginClass = loader.loadClass("com.example.MyPlugin");
Object plugin = pluginClass.getDeclaredConstructor().newInstance();

// To allow unloading: discard ALL references to loader, pluginClass, and any instances it created
Real-world example A plugin-based application (like an IDE supporting third-party extensions) uses a dedicated ClassLoader per plugin, allowing plugins to be loaded and, when properly designed to release all references, later garbage collected and effectively "unloaded" without restarting the entire application, isolating each plugin's classes from others.

Common follow-ups: What specifically prevents a ClassLoader and its loaded classes from being garbage collected, and how do you diagnose a classloader leak in a running application?;How does OSGi's module system build on custom class loading to provide more robust plugin isolation?