diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitPlugin.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitPlugin.java index 25ad28c8..f21d0afd 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitPlugin.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitPlugin.java @@ -31,7 +31,6 @@ import me.lucko.luckperms.api.Contexts; import me.lucko.luckperms.api.LuckPermsApi; import me.lucko.luckperms.api.platform.PlatformType; import me.lucko.luckperms.bukkit.calculators.BukkitCalculatorFactory; -import me.lucko.luckperms.bukkit.classloader.LPClassLoader; import me.lucko.luckperms.bukkit.contexts.BukkitContextManager; import me.lucko.luckperms.bukkit.contexts.WorldCalculator; import me.lucko.luckperms.bukkit.listeners.BukkitConnectionListener; @@ -96,7 +95,6 @@ import org.bukkit.plugin.java.JavaPlugin; import java.io.File; import java.io.InputStream; -import java.net.URL; import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; @@ -131,7 +129,6 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin { private DefaultsProvider defaultsProvider; private ChildPermissionProvider childPermissionProvider; private LocaleManager localeManager; - private LPClassLoader lpClassLoader; private DependencyManager dependencyManager; private CachedStateManager cachedStateManager; private ContextManager contextManager; @@ -156,7 +153,6 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin { senderFactory = new BukkitSenderFactory(this); log = new SenderLogger(this, getConsoleSender()); - lpClassLoader = LPClassLoader.obtainFor(this); dependencyManager = new DependencyManager(this); dependencyManager.loadDependencies(Collections.singleton(Dependency.CAFFEINE)); } @@ -393,11 +389,6 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin { getLog().info("Goodbye!"); } - @Override - public void loadUrlIntoClasspath(URL url) { - lpClassLoader.addURL(url); - } - public void tryVaultHook(boolean force) { if (vaultHookManager != null) { return; // already hooked diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/classloader/FallbackClassLoader.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/classloader/FallbackClassLoader.java deleted file mode 100644 index 9c8e17e0..00000000 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/classloader/FallbackClassLoader.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of LuckPerms, licensed under the MIT License. - * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package me.lucko.luckperms.bukkit.classloader; - -import lombok.RequiredArgsConstructor; - -import me.lucko.luckperms.common.dependencies.DependencyManager; -import me.lucko.luckperms.common.plugin.LuckPermsPlugin; - -import java.net.URL; - -/** - * A dummy implementation of {@link LPClassLoader} which just falls back to the - * reflection method used by other platforms. - */ -@RequiredArgsConstructor -public class FallbackClassLoader implements LPClassLoader { - private final LuckPermsPlugin plugin; - - @Override - public void addURL(URL url) { - DependencyManager.loadUrlIntoClassLoader(url, plugin.getClass().getClassLoader()); - } -} diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/classloader/InjectedClassLoader.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/classloader/InjectedClassLoader.java deleted file mode 100644 index fd2648bb..00000000 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/classloader/InjectedClassLoader.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * This file is part of LuckPerms, licensed under the MIT License. - * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package me.lucko.luckperms.bukkit.classloader; - -import lombok.RequiredArgsConstructor; -import lombok.experimental.Delegate; - -import org.bukkit.plugin.java.JavaPlugin; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * A fake classloader instance which sits in-front of a PluginClassLoader, and - * attempts to load classes from it's own sources before allowing the PCL to load - * the class. - * - * This allows us to inject extra URL sources into the plugin's classloader at - * runtime. - */ -public class InjectedClassLoader extends URLClassLoader implements LPClassLoader { - - public static InjectedClassLoader inject(JavaPlugin plugin) throws Exception { - // get the plugin's PluginClassLoader instance - ClassLoader classLoader = plugin.getClass().getClassLoader(); - - // get a ref to the PCL class - Class pclClass = Class.forName("org.bukkit.plugin.java.PluginClassLoader"); - - // extract the 'classes' cache map - Field classesField = pclClass.getDeclaredField("classes"); - classesField.setAccessible(true); - - // obtain the classes instance from the classloader - //noinspection unchecked - Map> old = (Map) classesField.get(classLoader); - - // init a new InjectedClassLoader to read from - InjectedClassLoader newLoader = new InjectedClassLoader(); - - // replace the 'classes' cache map with our own. - classesField.set(classLoader, new DelegatingClassMap(newLoader, old)); - - return newLoader; - } - - static { - try { - Method method = ClassLoader.class.getDeclaredMethod("registerAsParallelCapable"); - if (method != null) { - method.setAccessible(true); - method.invoke(null); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - private final Map> cache = new ConcurrentHashMap<>(); - - private InjectedClassLoader() { - super(new URL[0]); - } - - @Override - public void addURL(URL url) { - super.addURL(url); - } - - private Class lookup(String name) { - // try the cache - Class clazz = cache.get(name); - if (clazz != null) { - return clazz; - } - - try { - // attempt to load - clazz = loadClass(name); - - // if successful, add to the cache file - cache.put(name, clazz); - return clazz; - } catch (ClassNotFoundException e) { - return null; - } - } - - /** - * A fake map instance which effectively allows us to override the behaviour - * of #findClass in PluginClassLoader. - */ - @RequiredArgsConstructor - private static final class DelegatingClassMap implements Map> { - private final InjectedClassLoader loader; - - // delegate all other calls to the original map - @Delegate(excludes = Exclude.class) - private final Map> delegate; - - // override the #get call, so we can attempt to load the class ourselves. - @Override - public Class get(Object key) { - String className = ((String) key); - - Class clazz = loader.lookup(className); - if (clazz != null) { - return clazz; - } else { - return delegate.get(className); - } - } - - private interface Exclude { - Class get(Object key); - } - } - -} diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/classloader/LPClassLoader.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/classloader/LPClassLoader.java deleted file mode 100644 index ab985e30..00000000 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/classloader/LPClassLoader.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of LuckPerms, licensed under the MIT License. - * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package me.lucko.luckperms.bukkit.classloader; - -import me.lucko.luckperms.bukkit.LPBukkitPlugin; - -import java.net.URL; - -/** - * An interface over a {@link org.bukkit.plugin.java.JavaPlugin}'s PluginClassLoader. - */ -public interface LPClassLoader { - - static LPClassLoader obtainFor(LPBukkitPlugin plugin) { - try { - // try to inject into the classloader - return InjectedClassLoader.inject(plugin); - } catch (Exception e) { - // fallback to a reflection based method - return new FallbackClassLoader(plugin); - } - } - - /** - * Adds a URL to the classloader - * - * @param url the url to add - */ - void addURL(URL url); - -} diff --git a/common/src/main/java/me/lucko/luckperms/common/dependencies/DependencyManager.java b/common/src/main/java/me/lucko/luckperms/common/dependencies/DependencyManager.java index 9695e452..42bca978 100644 --- a/common/src/main/java/me/lucko/luckperms/common/dependencies/DependencyManager.java +++ b/common/src/main/java/me/lucko/luckperms/common/dependencies/DependencyManager.java @@ -103,10 +103,14 @@ public class DependencyManager { dependencies.add(Dependency.JEDIS); } - // don't load slf4j or configurate dependencies on sponge, as they're already present - if (plugin.getServerType() == PlatformType.SPONGE) { + // don't load slf4j if it's already present + if (classExists("org.slf4j.Logger") && classExists("org.slf4j.LoggerFactory")) { dependencies.remove(Dependency.SLF4J_API); dependencies.remove(Dependency.SLF4J_SIMPLE); + } + + // don't load configurate dependencies on sponge + if (plugin.getServerType() == PlatformType.SPONGE) { dependencies.remove(Dependency.CONFIGURATE_CORE); dependencies.remove(Dependency.CONFIGURATE_GSON); dependencies.remove(Dependency.CONFIGURATE_YAML); @@ -182,20 +186,14 @@ public class DependencyManager { } } - private void loadJar(File file) { + private void loadJar(File file) { // get the classloader to load into - try { - plugin.loadUrlIntoClasspath(file.toURI().toURL()); - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } - } + ClassLoader classLoader = plugin.getClass().getClassLoader(); - public static void loadUrlIntoClassLoader(URL url, ClassLoader classLoader) { if (classLoader instanceof URLClassLoader) { try { - ADD_URL_METHOD.invoke(classLoader, url); - } catch (IllegalAccessException | InvocationTargetException e) { + ADD_URL_METHOD.invoke(classLoader, file.toURI().toURL()); + } catch (IllegalAccessException | InvocationTargetException | MalformedURLException e) { throw new RuntimeException("Unable to invoke URLClassLoader#addURL", e); } } else { @@ -203,4 +201,13 @@ public class DependencyManager { } } + private static boolean classExists(String className) { + try { + Class.forName(className); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } + } diff --git a/common/src/main/java/me/lucko/luckperms/common/plugin/LuckPermsPlugin.java b/common/src/main/java/me/lucko/luckperms/common/plugin/LuckPermsPlugin.java index 92db9c37..d945cdd1 100644 --- a/common/src/main/java/me/lucko/luckperms/common/plugin/LuckPermsPlugin.java +++ b/common/src/main/java/me/lucko/luckperms/common/plugin/LuckPermsPlugin.java @@ -55,7 +55,6 @@ import me.lucko.luckperms.common.verbose.VerboseHandler; import java.io.File; import java.io.InputStream; -import java.net.URL; import java.util.Collections; import java.util.List; import java.util.Map; @@ -155,15 +154,6 @@ public interface LuckPermsPlugin { */ DependencyManager getDependencyManager(); - /** - * Loads a dependency into the plugins classpath - * - * @param url the url to load - */ - default void loadUrlIntoClasspath(URL url) { - DependencyManager.loadUrlIntoClassLoader(url, getClass().getClassLoader()); - } - /** * Gets the context manager. * This object handles context accumulation for all players on the platform.