mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-11-24 03:25:19 +01:00
Print more useful debug message when a LinkageError is thrown due to bad SLF4J classloading
This is a longstanding issue, mostly caused by plugins with bad Maven shade configurations. https://github.com/lucko/LuckPerms/issues?q=slf4j
This commit is contained in:
parent
2839c36ea2
commit
ec7994a561
@ -39,6 +39,7 @@ import org.bukkit.Server;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Path;
|
||||
@ -268,6 +269,14 @@ public class LPBukkitBootstrap extends JavaPlugin implements LuckPermsBootstrap
|
||||
return player != null && player.isOnline();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String identifyClassLoader(ClassLoader classLoader) {
|
||||
if (classLoader instanceof org.bukkit.plugin.java.PluginClassLoader) {
|
||||
return ((org.bukkit.plugin.java.PluginClassLoader) classLoader).getPlugin().getName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean checkIncompatibleVersion() {
|
||||
try {
|
||||
Class.forName("com.google.gson.JsonElement");
|
||||
|
@ -36,6 +36,9 @@ import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter;
|
||||
import net.luckperms.api.platform.Platform;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
import net.md_5.bungee.api.plugin.PluginDescription;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Path;
|
||||
@ -260,6 +263,16 @@ public class LPBungeeBootstrap extends Plugin implements LuckPermsBootstrap {
|
||||
return getProxy().getPlayer(uniqueId) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String identifyClassLoader(ClassLoader classLoader) throws Exception {
|
||||
Class<?> pluginClassLoader = Class.forName("net.md_5.bungee.api.plugin.PluginClassloader");
|
||||
if (pluginClassLoader.isInstance(classLoader)) {
|
||||
PluginDescription desc = (PluginDescription) pluginClassLoader.getDeclaredField("desc").get(classLoader);
|
||||
return desc.getName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean checkIncompatibleVersion() {
|
||||
try {
|
||||
Class<?> aClass = Class.forName("com.google.gson.internal.bind.TreeTypeAdapter");
|
||||
|
@ -214,4 +214,17 @@ public interface LuckPermsBootstrap {
|
||||
*/
|
||||
boolean isPlayerOnline(UUID uniqueId);
|
||||
|
||||
/**
|
||||
* Attempts to identify the plugin behind the given classloader.
|
||||
*
|
||||
* <p>Used for giving more helpful log messages when things break.</p>
|
||||
*
|
||||
* @param classLoader the classloader to identify
|
||||
* @return the name of the classloader source
|
||||
* @throws Exception anything
|
||||
*/
|
||||
default @Nullable String identifyClassLoader(ClassLoader classLoader) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -147,7 +147,7 @@ public class SqlStorage implements StorageImplementation {
|
||||
|
||||
@Override
|
||||
public void init() throws Exception {
|
||||
this.connectionFactory.init();
|
||||
this.connectionFactory.init(this.plugin);
|
||||
|
||||
boolean tableExists;
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
|
@ -25,6 +25,8 @@
|
||||
|
||||
package me.lucko.luckperms.common.storage.implementation.sql.connection;
|
||||
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collections;
|
||||
@ -35,7 +37,7 @@ public interface ConnectionFactory {
|
||||
|
||||
String getImplementationName();
|
||||
|
||||
void init();
|
||||
void init(LuckPermsPlugin plugin);
|
||||
|
||||
void shutdown() throws Exception;
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
package me.lucko.luckperms.common.storage.implementation.sql.connection.file;
|
||||
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.implementation.sql.connection.ConnectionFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -44,7 +45,7 @@ abstract class FlatfileConnectionFactory implements ConnectionFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
public void init(LuckPermsPlugin plugin) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -25,9 +25,12 @@
|
||||
|
||||
package me.lucko.luckperms.common.storage.implementation.sql.connection.hikari;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.plugin.logging.PluginLogger;
|
||||
import me.lucko.luckperms.common.storage.implementation.sql.connection.ConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.misc.StorageCredentials;
|
||||
|
||||
@ -36,6 +39,7 @@ import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@ -73,8 +77,17 @@ public abstract class HikariConnectionFactory implements ConnectionFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
HikariConfig config = new HikariConfig();
|
||||
public void init(LuckPermsPlugin plugin) {
|
||||
HikariConfig config;
|
||||
try {
|
||||
config = new HikariConfig();
|
||||
} catch (LinkageError e) {
|
||||
// dumb plugins seem to keep doing stupid stuff with shading of SLF4J and Log4J.
|
||||
// detect this and print a more useful error message.
|
||||
handleLinkageError(e, plugin);
|
||||
throw e;
|
||||
}
|
||||
|
||||
config.setPoolName("luckperms-hikari");
|
||||
|
||||
appendConfigurationInfo(config);
|
||||
@ -141,4 +154,38 @@ public abstract class HikariConnectionFactory implements ConnectionFactory {
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
|
||||
private static void handleLinkageError(LinkageError linkageError, LuckPermsPlugin plugin) {
|
||||
List<String> noteworthyClasses = ImmutableList.of(
|
||||
"org.slf4j.LoggerFactory",
|
||||
"org.slf4j.ILoggerFactory",
|
||||
"org.apache.logging.slf4j.Log4jLoggerFactory",
|
||||
"org.apache.logging.log4j.spi.LoggerContext",
|
||||
"org.apache.logging.log4j.spi.AbstractLoggerAdapter",
|
||||
"org.slf4j.impl.StaticLoggerBinder"
|
||||
);
|
||||
|
||||
PluginLogger logger = plugin.getLogger();
|
||||
logger.warn("A " + linkageError.getClass().getSimpleName() + " has occurred whilst initialising Hikari. This is likely due to classloading conflicts between other plugins.");
|
||||
logger.warn("Please check for other plugins below (and try loading LuckPerms without them installed) before reporting the issue.");
|
||||
|
||||
for (String className : noteworthyClasses) {
|
||||
Class<?> clazz;
|
||||
try {
|
||||
clazz = Class.forName(className);
|
||||
} catch (Exception ex) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ClassLoader loader = clazz.getClassLoader();
|
||||
String loaderName;
|
||||
try {
|
||||
loaderName = plugin.getBootstrap().identifyClassLoader(loader) + " (" + loader.toString() + ")";
|
||||
} catch (Exception e) {
|
||||
loaderName = loader.toString();
|
||||
}
|
||||
|
||||
logger.warn("Class " + className + " has been loaded by: " + loaderName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user