Skip to content

Commit

Permalink
Add workaround for weird plugin class loading
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexProgrammerDE committed Mar 11, 2024
1 parent d1cef49 commit 7cd4f49
Showing 1 changed file with 16 additions and 4 deletions.
20 changes: 16 additions & 4 deletions common/src/main/java/com/soulfiremc/util/SFContextClassLoader.java
Expand Up @@ -33,6 +33,8 @@ public class SFContextClassLoader extends ClassLoader {
@Getter private final List<ClassLoader> childClassLoaders = new ArrayList<>();
private final Method findLoadedClassMethod;
private final ClassLoader platformClassLoader = ClassLoader.getSystemClassLoader().getParent();
// Prevent infinite loop when plugins are looking for classes inside this class loader
private boolean lookingThroughPlugins = false;

public SFContextClassLoader() {
super(createLibClassLoader());
Expand Down Expand Up @@ -92,26 +94,36 @@ protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundE
// Ignore
}

var classData = loadClassData(this.getParent(), name);
if (classData == null) {
// In the next step, we pretend we own the classes of either the parent or the child class loaders
var parentClassData = getClassBytes(this.getParent(), name);
if (parentClassData == null) {
if (lookingThroughPlugins) {
throw new ClassNotFoundException(name);
}

lookingThroughPlugins = true;

// Check if child class loaders can load the class
for (var childClassLoader : childClassLoaders) {
try {
var pluginClass = loadClassFromClassLoader(childClassLoader, name, resolve);
if (pluginClass != null) {
lookingThroughPlugins = false;
return pluginClass;
}
} catch (ClassNotFoundException ignored) {
// Ignore
}
}

lookingThroughPlugins = false;
throw new ClassNotFoundException(name);
}

c = defineClass(name, classData, 0, classData.length);
c = defineClass(name, parentClassData, 0, parentClassData.length);
}

// Resolve the class if requested
if (resolve) {
resolveClass(c);
}
Expand Down Expand Up @@ -146,7 +158,7 @@ private Class<?> getMethodsClass() throws ClassNotFoundException {
}
}

private byte[] loadClassData(ClassLoader classLoader, String className) {
private byte[] getClassBytes(ClassLoader classLoader, String className) {
var classPath = className.replace('.', '/') + ".class";

try (var inputStream = classLoader.getResourceAsStream(classPath)) {
Expand Down

0 comments on commit 7cd4f49

Please sign in to comment.