Warn if the API was classloaded by another plugin

This commit is contained in:
Luck 2022-02-09 21:08:18 +00:00
parent d45d9a295b
commit 59f3866e36
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
6 changed files with 85 additions and 3 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -0,0 +1,40 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* 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();
}

View File

@ -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;
}