Skip to content

Commit

Permalink
Invoke ClassLoader on non-loaded supertypes of a predefined class.
Browse files Browse the repository at this point in the history
  • Loading branch information
peter-hofer committed Jul 16, 2021
1 parent 108f549 commit 59a0d8d
Showing 1 changed file with 38 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -158,18 +158,21 @@ public static boolean loadClassIfNotLoaded(ClassLoader classLoader, ProtectionDo
}

private boolean loadClass0(ClassLoader classLoader, ProtectionDomain protectionDomain, Class<?> clazz) {
if (DynamicHub.fromClass(clazz).isLoaded()) {
return false;
}

loadSuperType(clazz, clazz.getSuperclass(), classLoader);
for (Class<?> intf : clazz.getInterfaces()) {
loadSuperType(clazz, intf, classLoader);
}

lock.lock();
try {
boolean alreadyLoaded = (loadedClassesByName.get(clazz.getName()) == clazz);
if (alreadyLoaded) {
if (DynamicHub.fromClass(clazz).isLoaded()) {
return false;
}

throwIfUnresolvable(clazz.getSuperclass(), classLoader);
for (Class<?> intf : clazz.getInterfaces()) {
throwIfUnresolvable(intf, classLoader);
}

/*
* The following is part of the locked block so that other threads can observe only the
* initialized values once the class can be found.
Expand All @@ -186,20 +189,43 @@ private boolean loadClass0(ClassLoader classLoader, ProtectionDomain protectionD
}
}

private static void loadSuperType(Class<?> clazz, Class<?> supertype, ClassLoader classLoader) {
if (supertype == null) {
return;
}
if (classLoader != null && !DynamicHub.fromClass(supertype).isLoaded()) {
Class<?> loaded;
try {
loaded = classLoader.loadClass(supertype.getName());
} catch (ClassNotFoundException e) {
throw throwUnresolvable(supertype, e);
}
if (loaded != supertype) {
throw new LinkageError("Loader " + classLoader + " supplied unexpected class " + loaded.getName() + " for supertype of " + clazz.getName() + " when expecting " + supertype.getName());
}
} else {
throwIfUnresolvable(supertype, classLoader);
}
}

public static void throwIfUnresolvable(Class<?> clazz, ClassLoader classLoader) {
if (clazz == null) {
return;
}
DynamicHub hub = DynamicHub.fromClass(clazz);
if (!hub.isLoaded() || !ClassUtil.isSameOrParentLoader(clazz.getClassLoader(), classLoader)) {
String name = clazz.getName();
// NoClassDefFoundError with ClassNotFoundException required by Java VM spec, 5.3
NoClassDefFoundError error = new NoClassDefFoundError(name.replace('.', '/'));
error.initCause(new ClassNotFoundException(name));
throw error;
throw throwUnresolvable(clazz, null);
}
}

/** Throw a NoClassDefFoundError with ClassNotFoundException as required by Java VM spec 5.3. */
private static RuntimeException throwUnresolvable(Class<?> clazz, ClassNotFoundException cause) {
String name = clazz.getName();
NoClassDefFoundError error = new NoClassDefFoundError(name.replace('.', '/'));
error.initCause((cause != null) ? cause : new ClassNotFoundException(name));
throw error;
}

static Class<?> getLoadedForNameOrNull(String name, ClassLoader classLoader) {
Class<?> clazz = singleton().getLoaded(name);
if (clazz == null || !ClassUtil.isSameOrParentLoader(clazz.getClassLoader(), classLoader)) {
Expand Down

0 comments on commit 59a0d8d

Please sign in to comment.