Search code examples
javaclassloader

What is the first parameter of standard ClassLoader class constructor for?


The title says it all, here's the code:

private ClassLoader(Void unused, ClassLoader parent) {
    this.parent = parent;
    if (ParallelLoaders.isRegistered(this.getClass())) {
        parallelLockMap = new ConcurrentHashMap<>();
        package2certs = new ConcurrentHashMap<>();
        domains =
            Collections.synchronizedSet(new HashSet<ProtectionDomain>());
        assertionLock = new Object();
    } else {
        // no finer-grained lock; lock on the classloader instance
        parallelLockMap = null;
        package2certs = new Hashtable<>();
        domains = new HashSet<>();
        assertionLock = this;
    }
}

Solution

  • That looks like a clever trick to call the security check before the class loader can be instantiated.

    A quick experiment confirms the static method is called before any initializers:

    public class InitializerTest {
        {
            System.out.println("Initializer block");
        }
    
        private InitializerTest(Void v) {
            System.out.println("Constructor");
        }
    
        protected InitializerTest() {
            this(staticMethod());
        }
    
        private static Void staticMethod() {
            System.out.println("Static method");
            return null;
        }
    }
    

    Which outputs:

    Static method
    Initializer block
    Constructor
    

    Clearly it will be more secure to never allow a rogue ClassLoader subclass to be instantiated than fail it after instantiation. E.g. even if the superclass failed in its first initializer block, the instance is out there - perhaps an exploit in the finalize() method on the subclass would be possible?