diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitBootstrap.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitBootstrap.java index fd9333f76..949af47bc 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitBootstrap.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/LPBukkitBootstrap.java @@ -27,6 +27,7 @@ package me.lucko.luckperms.bukkit; import me.lucko.luckperms.bukkit.util.NullSafeConsoleCommandSender; import me.lucko.luckperms.common.loader.LoaderBootstrap; +import me.lucko.luckperms.common.plugin.bootstrap.BootstrappedWithLoader; import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap; import me.lucko.luckperms.common.plugin.classpath.ClassPathAppender; import me.lucko.luckperms.common.plugin.classpath.JarInJarClassPathAppender; @@ -56,7 +57,7 @@ import java.util.logging.Logger; /** * Bootstrap plugin for LuckPerms running on Bukkit. */ -public class LPBukkitBootstrap implements LuckPermsBootstrap, LoaderBootstrap { +public class LPBukkitBootstrap implements LuckPermsBootstrap, LoaderBootstrap, BootstrappedWithLoader { private final JavaPlugin loader; /** @@ -111,6 +112,7 @@ public class LPBukkitBootstrap implements LuckPermsBootstrap, LoaderBootstrap { // provide adapters + @Override public JavaPlugin getLoader() { return this.loader; } diff --git a/bungee/src/main/java/me/lucko/luckperms/bungee/LPBungeeBootstrap.java b/bungee/src/main/java/me/lucko/luckperms/bungee/LPBungeeBootstrap.java index 3174c80a0..5caccd210 100644 --- a/bungee/src/main/java/me/lucko/luckperms/bungee/LPBungeeBootstrap.java +++ b/bungee/src/main/java/me/lucko/luckperms/bungee/LPBungeeBootstrap.java @@ -27,6 +27,7 @@ package me.lucko.luckperms.bungee; import me.lucko.luckperms.bungee.util.RedisBungeeUtil; import me.lucko.luckperms.common.loader.LoaderBootstrap; +import me.lucko.luckperms.common.plugin.bootstrap.BootstrappedWithLoader; import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap; import me.lucko.luckperms.common.plugin.classpath.ClassPathAppender; import me.lucko.luckperms.common.plugin.classpath.JarInJarClassPathAppender; @@ -56,7 +57,7 @@ import java.util.logging.Logger; /** * Bootstrap plugin for LuckPerms running on BungeeCord. */ -public class LPBungeeBootstrap implements LuckPermsBootstrap, LoaderBootstrap { +public class LPBungeeBootstrap implements LuckPermsBootstrap, LoaderBootstrap, BootstrappedWithLoader { private final Plugin loader; /** @@ -101,6 +102,7 @@ public class LPBungeeBootstrap implements LuckPermsBootstrap, LoaderBootstrap { // provide adapters + @Override public Plugin getLoader() { return this.loader; } diff --git a/common/src/main/java/me/lucko/luckperms/common/api/LuckPermsApiProvider.java b/common/src/main/java/me/lucko/luckperms/common/api/LuckPermsApiProvider.java index 77aecbc4f..143df9e4f 100644 --- a/common/src/main/java/me/lucko/luckperms/common/api/LuckPermsApiProvider.java +++ b/common/src/main/java/me/lucko/luckperms/common/api/LuckPermsApiProvider.java @@ -41,8 +41,12 @@ import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.event.AbstractEventBus; import me.lucko.luckperms.common.messaging.LuckPermsMessagingService; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; +import me.lucko.luckperms.common.plugin.bootstrap.BootstrappedWithLoader; +import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap; +import me.lucko.luckperms.common.plugin.logging.PluginLogger; import net.luckperms.api.LuckPerms; +import net.luckperms.api.LuckPermsProvider; import net.luckperms.api.actionlog.ActionLogger; import net.luckperms.api.context.ContextManager; import net.luckperms.api.messaging.MessagingService; @@ -93,6 +97,37 @@ public class LuckPermsApiProvider implements LuckPerms { this.metaStackFactory = new ApiMetaStackFactory(plugin); } + public void ensureApiWasLoadedByPlugin() { + LuckPermsBootstrap bootstrap = this.plugin.getBootstrap(); + ClassLoader pluginClassLoader; + if (bootstrap instanceof BootstrappedWithLoader) { + pluginClassLoader = ((BootstrappedWithLoader) bootstrap).getLoader().getClass().getClassLoader(); + } else { + pluginClassLoader = bootstrap.getClass().getClassLoader(); + } + + for (Class apiClass : new Class[]{LuckPerms.class, LuckPermsProvider.class}) { + ClassLoader apiClassLoader = apiClass.getClassLoader(); + + if (!apiClassLoader.equals(pluginClassLoader)) { + String guilty = "unknown"; + try { + guilty = bootstrap.identifyClassLoader(apiClassLoader); + } catch (Exception e) { + // ignore + } + + PluginLogger logger = this.plugin.getLogger(); + logger.warn("It seems that the LuckPerms API has been (class)loaded by a plugin other than LuckPerms!"); + logger.warn("The API was loaded by " + apiClassLoader + " (" + guilty + ") and the " + + "LuckPerms plugin was loaded by " + pluginClassLoader.toString() + "."); + logger.warn("This indicates that the other plugin has incorrectly \"shaded\" the " + + "LuckPerms API into its jar file. This can cause errors at runtime and should be fixed."); + return; + } + } + } + @Override public @NonNull String getServerName() { return this.plugin.getConfiguration().get(ConfigKeys.SERVER); diff --git a/common/src/main/java/me/lucko/luckperms/common/plugin/AbstractLuckPermsPlugin.java b/common/src/main/java/me/lucko/luckperms/common/plugin/AbstractLuckPermsPlugin.java index 4836b9e76..f6f2fd806 100644 --- a/common/src/main/java/me/lucko/luckperms/common/plugin/AbstractLuckPermsPlugin.java +++ b/common/src/main/java/me/lucko/luckperms/common/plugin/AbstractLuckPermsPlugin.java @@ -194,6 +194,7 @@ public abstract class AbstractLuckPermsPlugin implements LuckPermsPlugin { // register with the LP API this.apiProvider = new LuckPermsApiProvider(this); + this.apiProvider.ensureApiWasLoadedByPlugin(); this.eventDispatcher = new EventDispatcher(provideEventBus(this.apiProvider)); getBootstrap().getScheduler().executeAsync(GeneratedEventClass::preGenerate); ApiRegistrationUtil.registerProvider(this.apiProvider); diff --git a/common/src/main/java/me/lucko/luckperms/common/plugin/bootstrap/BootstrappedWithLoader.java b/common/src/main/java/me/lucko/luckperms/common/plugin/bootstrap/BootstrappedWithLoader.java new file mode 100644 index 000000000..d5cdb6f65 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/common/plugin/bootstrap/BootstrappedWithLoader.java @@ -0,0 +1,40 @@ +/* + * 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.common.plugin.bootstrap; + +/** + * A {@link LuckPermsBootstrap} that was bootstrapped by a loader. + */ +public interface BootstrappedWithLoader { + + /** + * Gets the loader object that did the bootstrapping. + * + * @return the loader + */ + Object getLoader(); + +} diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/LPNukkitBootstrap.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/LPNukkitBootstrap.java index 497f1d020..8dc90ad22 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/LPNukkitBootstrap.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/LPNukkitBootstrap.java @@ -26,6 +26,7 @@ package me.lucko.luckperms.nukkit; import me.lucko.luckperms.common.loader.LoaderBootstrap; +import me.lucko.luckperms.common.plugin.bootstrap.BootstrappedWithLoader; import me.lucko.luckperms.common.plugin.bootstrap.LuckPermsBootstrap; import me.lucko.luckperms.common.plugin.classpath.ClassPathAppender; import me.lucko.luckperms.common.plugin.classpath.JarInJarClassPathAppender; @@ -49,7 +50,7 @@ import java.util.concurrent.CountDownLatch; /** * Bootstrap plugin for LuckPerms running on Nukkit. */ -public class LPNukkitBootstrap implements LuckPermsBootstrap, LoaderBootstrap { +public class LPNukkitBootstrap implements LuckPermsBootstrap, LoaderBootstrap, BootstrappedWithLoader { private final PluginBase loader; /** @@ -91,6 +92,7 @@ public class LPNukkitBootstrap implements LuckPermsBootstrap, LoaderBootstrap { // provide adapters + @Override public PluginBase getLoader() { return this.loader; }