From 4598435dd4e1e3187f4ed58e770785ec08878c7d Mon Sep 17 00:00:00 2001 From: Luck Date: Sun, 13 Jun 2021 12:46:02 +0100 Subject: [PATCH] Fix extension loading causing whole plugin to error --- .../extension/SimpleExtensionManager.java | 13 ++++------ .../ReflectionClassPathAppender.java | 25 +++++++++++++++---- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/common/src/main/java/me/lucko/luckperms/common/extension/SimpleExtensionManager.java b/common/src/main/java/me/lucko/luckperms/common/extension/SimpleExtensionManager.java index 05598d03a..f271e50ea 100644 --- a/common/src/main/java/me/lucko/luckperms/common/extension/SimpleExtensionManager.java +++ b/common/src/main/java/me/lucko/luckperms/common/extension/SimpleExtensionManager.java @@ -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 { diff --git a/common/src/main/java/me/lucko/luckperms/common/plugin/classpath/ReflectionClassPathAppender.java b/common/src/main/java/me/lucko/luckperms/common/plugin/classpath/ReflectionClassPathAppender.java index ebb175227..2aec61edb 100644 --- a/common/src/main/java/me/lucko/luckperms/common/plugin/classpath/ReflectionClassPathAppender.java +++ b/common/src/main/java/me/lucko/luckperms/common/plugin/classpath/ReflectionClassPathAppender.java @@ -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: //