Fix extension loading causing whole plugin to error

This commit is contained in:
Luck 2021-06-13 12:46:02 +01:00
parent 51202924af
commit 4598435dd4
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
2 changed files with 25 additions and 13 deletions

View File

@ -28,6 +28,7 @@ package me.lucko.luckperms.common.extension;
import com.google.gson.JsonObject;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.plugin.classpath.ReflectionClassPathAppender;
import me.lucko.luckperms.common.util.gson.GsonProvider;
import net.luckperms.api.LuckPerms;
@ -42,8 +43,6 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
@ -98,7 +97,7 @@ public class SimpleExtensionManager implements ExtensionManager, AutoCloseable {
if (path.getFileName().toString().endsWith(".jar")) {
try {
loadExtension(path);
} catch (IOException e) {
} catch (Exception e) {
this.plugin.getLogger().warn("Exception loading extension from " + path, e);
}
}
@ -146,7 +145,7 @@ public class SimpleExtensionManager implements ExtensionManager, AutoCloseable {
if (useParentClassLoader && isJarInJar()) {
try {
addJarToParentClasspath(path);
} catch (Exception e) {
} catch (Throwable e) {
throw new RuntimeException("Exception whilst classloading extension", e);
}
} else {
@ -200,16 +199,14 @@ public class SimpleExtensionManager implements ExtensionManager, AutoCloseable {
return thisClassLoaderName.equals("me.lucko.luckperms.common.loader.JarInJarClassLoader");
}
@Deprecated
private static void addJarToParentClasspath(Path path) throws Exception {
ClassLoader parentClassLoader = SimpleExtensionManager.class.getClassLoader().getParent();
if (!(parentClassLoader instanceof URLClassLoader)) {
throw new RuntimeException("useParentClassLoader is true but parent is not a URLClassLoader");
}
Method addUrlMethod = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
addUrlMethod.setAccessible(true);
addUrlMethod.invoke(parentClassLoader, path.toUri().toURL());
ReflectionClassPathAppender.addUrl(((URLClassLoader) parentClassLoader), path.toUri().toURL());
}
private static final class LoadedExtension {

View File

@ -43,16 +43,32 @@ public class ReflectionClassPathAppender implements ClassPathAppender {
try {
openUrlClassLoaderModule();
} catch (Throwable e) {
// ignore exception - will throw on Java 8 since the Module classes don't exist
// ignore
}
// Get the protected 'addURL' method on URLClassLoader and set it to accessible.
try {
ADD_URL_METHOD = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
ADD_URL_METHOD.setAccessible(true);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
try {
ADD_URL_METHOD.setAccessible(true);
} catch (Throwable e) {
new RuntimeException("LuckPerms is unable to access the URLClassLoader#addURL method using reflection. \n" +
"You may be able to fix this problem by adding the following command-line argument " +
"directly after the 'java' command in your start script: \n'--add-opens java.base/java.lang=ALL-UNNAMED'", e).printStackTrace();
}
}
/**
* Adds the given {@link URL} to the class loader.
*
* @param classLoader the class loader
* @param url the url to add
*/
public static void addUrl(URLClassLoader classLoader, URL url) throws ReflectiveOperationException {
ADD_URL_METHOD.invoke(classLoader, url);
}
private final URLClassLoader classLoader;
@ -69,13 +85,12 @@ public class ReflectionClassPathAppender implements ClassPathAppender {
@Override
public void addJarToClasspath(Path file) {
try {
ADD_URL_METHOD.invoke(this.classLoader, file.toUri().toURL());
addUrl(this.classLoader, file.toUri().toURL());
} catch (ReflectiveOperationException | MalformedURLException e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("JavaReflectionMemberAccess")
private static void openUrlClassLoaderModule() throws Exception {
// This is effectively calling:
//