Java › Class Loading & Bytecode Verification
How does the same class name loaded by two different ClassLoaders create two genuinely distinct types in the JVM, and what problems does this cause (such as with singletons or ClassCastException)?
AdvancedAnswer
The JVM's identity for a loaded class is the pair (fully-qualified class name, defining ClassLoader) -- meaning the exact same .class file loaded by two different ClassLoader instances produces two entirely separate, mutually-incompatible Class objects, even though they share an identical name and bytecode; this breaks assumptions like a singleton pattern (each ClassLoader would have its own separate "singleton" instance) and causes confusing ClassCastException errors when code holding a reference obtained via one ClassLoader attempts to cast it to the type as seen by a different ClassLoader, since instanceof and casting checks are ClassLoader-aware, not just name-aware.
// Conceptual illustration: same class name, different loaders = different types
ClassLoader loader1 = new URLClassLoader(urls, null);
ClassLoader loader2 = new URLClassLoader(urls, null);
Class<?> classFromLoader1 = loader1.loadClass("com.example.MyClass");
Class<?> classFromLoader2 = loader2.loadClass("com.example.MyClass");
System.out.println(classFromLoader1 == classFromLoader2); // false! Different Class objects entirely
// An instance created via loader1's class CANNOT be cast to loader2's version of the same-named classReal-world example An application server hosting multiple independently-deployed web applications, each with its own isolated ClassLoader, experiences a confusing ClassCastException when two applications unexpectedly share a library instance across their supposedly-isolated ClassLoader boundaries, traced to the JVM correctly treating the same-named class loaded by each application's separate ClassLoader as fundamentally different types.