Hi all, I've long had an impression that all class loaders in an loadClass() chain should be recorded as initiating loaders. That knowledge comes from Inside the Java Virtual Machine, 2nd Edition [1]: But it looks like that's an incorrect impression. According to the JVMS2e 5.3.2 [2], the "Otherwise" paragraph, only when the JVM initiates a class loading process, the loader directly invoked by the JVM will be recorded as the initiating loader; the ones in the middle of the delegation chain won't be recorded. A loader whose loadClass() is called explicitly (and successfully completed) from Java code isn't necessarily recorded as an initiating loader. Using the example in [1] in the "Now imagine" paragraph, only Cindy should be an initiating loader of java.io.FileReader; neither Mom nor Grandma should be recorded as an initiating loader. I've tried writing an actual code to emulate the example, and on JDK6, it shows the description in [1] is wrong. ----------------------------------------------- TestInitiatingLoader.java import java.io.*; import java.net.*; public class TestInitiatingLoader { public static void main(String[] args) throws Exception { Grandma grandma = new Grandma(); Mom mom = new Mom(grandma); Cindy cindy = new Cindy(mom); cindy.loadClass("Dummy").newInstance(); // force class init final String reader = "java.io.FileReader"; printStats(grandma, reader); // false printStats(mom, reader); // false printStats(cindy, reader); // true } private static void printStats(LoadedClassQueryable loader, String name) { System.out.printf("Is %s an initiating loader of %s: %b\n", loader.getClass().getName(), name, loader.foundLoadedClass(name)); } } interface LoadedClassQueryable { boolean foundLoadedClass(String name); } class Cindy extends URLClassLoader implements LoadedClassQueryable { public Cindy(ClassLoader parent) { super(makeArgs(), parent); } private static URL[] makeArgs() { try { return new URL[] { new File(".").toURI().toURL() }; } catch (Exception e) { e.printStackTrace(); return new URL[] { }; } } @Override public Class<?> loadClass(String name) throws ClassNotFoundException { if ("Dummy".equals(name)) { // force Cindy to load this Dummy class return findClass("Dummy"); } return super.loadClass(name); } @Override public boolean foundLoadedClass(String name) { return findLoadedClass(name) != null; } } class Mom extends ClassLoader implements LoadedClassQueryable { public Mom(ClassLoader parent) { super(parent); } @Override public boolean foundLoadedClass(String name) { return findLoadedClass(name) != null; } } // use system class loader as parent class Grandma extends ClassLoader implements LoadedClassQueryable { @Override public boolean foundLoadedClass(String name) { return findLoadedClass(name) != null; } } ----------------------------------------------- Dummy.java import java.io.*; public class Dummy { static { // Dummy should be loaded by Cindy. // So Cindy will be recorded as an initiating loader for java.io.FileReader try { new FileReader("Dummy.class").close(); } catch (Exception e) { e.printStackTrace(); } } } ----------------------------------------------- Could anybody clarify which loaders are supposed to be recorded as an initiating loader? [1]: http://www.artima.com/insidejvm/ed2/linkmod3.html [2]: http://java.sun.com/docs/books/jvms/second_edition/html/ConstantPool.doc.html#79441