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;
}
}
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?