mirror of
https://github.com/EngineHub/WorldEdit.git
synced 2025-02-05 13:00:30 +08:00
Play dirty because bukkit classloading is bad. (#2043)
* Play dirty because bukkit classloading is bad. Fixes #2042. * Make logging more Bukkit-friendly. * Checkstyle
This commit is contained in:
parent
e2ab12c375
commit
eac5b51b0f
@ -21,13 +21,12 @@
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.PluginClassLoader;
|
||||
|
||||
import java.security.CodeSource;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@ -42,8 +41,20 @@
|
||||
*/
|
||||
public class ClassSourceValidator {
|
||||
|
||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||
private static final String SEPARATOR_LINE = Strings.repeat("*", 46);
|
||||
private static final Method loadClass;
|
||||
|
||||
static {
|
||||
Method tmp;
|
||||
try {
|
||||
tmp = PluginClassLoader.class.getDeclaredMethod("loadClass0",
|
||||
String.class, boolean.class, boolean.class, boolean.class);
|
||||
tmp.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
tmp = null;
|
||||
}
|
||||
loadClass = tmp;
|
||||
}
|
||||
|
||||
private final Plugin plugin;
|
||||
@Nullable
|
||||
@ -58,6 +69,9 @@ public ClassSourceValidator(Plugin plugin) {
|
||||
checkNotNull(plugin, "plugin");
|
||||
this.plugin = plugin;
|
||||
this.expectedClassLoader = plugin.getClass().getClassLoader();
|
||||
if (loadClass == null) {
|
||||
plugin.getLogger().info("Bukkit PluginClassLoader seems to have changed. Class source validation will be skipped.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -69,7 +83,7 @@ public ClassSourceValidator(Plugin plugin) {
|
||||
public Map<Class<?>, Plugin> findMismatches(List<Class<?>> classes) {
|
||||
checkNotNull(classes, "classes");
|
||||
|
||||
if (expectedClassLoader == null) {
|
||||
if (expectedClassLoader == null || loadClass == null) {
|
||||
return ImmutableMap.of();
|
||||
}
|
||||
|
||||
@ -80,14 +94,18 @@ public Map<Class<?>, Plugin> findMismatches(List<Class<?>> classes) {
|
||||
continue;
|
||||
}
|
||||
ClassLoader targetLoader = target.getClass().getClassLoader();
|
||||
if (!(targetLoader instanceof PluginClassLoader)) {
|
||||
continue;
|
||||
}
|
||||
for (Class<?> testClass : classes) {
|
||||
ClassLoader testSource = null;
|
||||
Class<?> targetClass;
|
||||
try {
|
||||
testSource = targetLoader.loadClass(testClass.getName()).getClassLoader();
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
targetClass = (Class<?>) loadClass.invoke(targetLoader, testClass.getName(), false, false, false);
|
||||
} catch (IllegalAccessException | InvocationTargetException ignored) {
|
||||
continue;
|
||||
}
|
||||
if (testSource != null && testSource != expectedClassLoader) {
|
||||
mismatches.putIfAbsent(testClass, testSource == targetLoader ? target : null);
|
||||
if (targetClass.getClassLoader() != expectedClassLoader) {
|
||||
mismatches.putIfAbsent(testClass, targetClass.getClassLoader() == targetLoader ? target : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -140,6 +158,6 @@ public void reportMismatches(List<Class<?>> classes) {
|
||||
builder.append("** Please report this to the plugins' developers.\n");
|
||||
builder.append(SEPARATOR_LINE).append("\n");
|
||||
|
||||
LOGGER.error(builder.toString());
|
||||
plugin.getLogger().severe(builder.toString());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user