Update Upstream

eac5b51 Play dirty because bukkit classloading is bad. (2043)
This commit is contained in:
NotMyFault 2022-03-02 20:48:49 +01:00
parent a23785632a
commit dafcd16a14
No known key found for this signature in database
GPG Key ID: 158F5701A6AAD00C

View File

@ -25,8 +25,11 @@ import com.sk89q.worldedit.internal.util.LogManagerCompat;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.PluginClassLoader;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -40,8 +43,20 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/ */
public class ClassSourceValidator { public class ClassSourceValidator {
private static final Logger LOGGER = LogManagerCompat.getLogger();
private static final String SEPARATOR_LINE = Strings.repeat("*", 46); 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; private final Plugin plugin;
@Nullable @Nullable
@ -56,6 +71,9 @@ public class ClassSourceValidator {
checkNotNull(plugin, "plugin"); checkNotNull(plugin, "plugin");
this.plugin = plugin; this.plugin = plugin;
this.expectedClassLoader = plugin.getClass().getClassLoader(); this.expectedClassLoader = plugin.getClass().getClassLoader();
if (loadClass == null) {
plugin.getLogger().info("Bukkit PluginClassLoader seems to have changed. Class source validation will be skipped.");
}
} }
/** /**
@ -67,7 +85,7 @@ public class ClassSourceValidator {
public Map<Class<?>, Plugin> findMismatches(List<Class<?>> classes) { public Map<Class<?>, Plugin> findMismatches(List<Class<?>> classes) {
checkNotNull(classes, "classes"); checkNotNull(classes, "classes");
if (expectedClassLoader == null) { if (expectedClassLoader == null || loadClass == null) {
return ImmutableMap.of(); return ImmutableMap.of();
} }
@ -78,14 +96,18 @@ public class ClassSourceValidator {
continue; continue;
} }
ClassLoader targetLoader = target.getClass().getClassLoader(); ClassLoader targetLoader = target.getClass().getClassLoader();
if (!(targetLoader instanceof PluginClassLoader)) {
continue;
}
for (Class<?> testClass : classes) { for (Class<?> testClass : classes) {
ClassLoader testSource = null; Class<?> targetClass;
try { try {
testSource = targetLoader.loadClass(testClass.getName()).getClassLoader(); targetClass = (Class<?>) loadClass.invoke(targetLoader, testClass.getName(), false, false, false);
} catch (ClassNotFoundException ignored) { } catch (IllegalAccessException | InvocationTargetException ignored) {
continue;
} }
if (testSource != null && testSource != expectedClassLoader) { if (targetClass.getClassLoader() != expectedClassLoader) {
mismatches.putIfAbsent(testClass, testSource == targetLoader ? target : null); mismatches.putIfAbsent(testClass, targetClass.getClassLoader() == targetLoader ? target : null);
} }
} }
} }
@ -139,7 +161,7 @@ public class ClassSourceValidator {
builder.append("** Please report this to the plugins' developers.\n"); builder.append("** Please report this to the plugins' developers.\n");
builder.append(SEPARATOR_LINE).append("\n"); builder.append(SEPARATOR_LINE).append("\n");
LOGGER.error(builder.toString()); plugin.getLogger().severe(builder.toString());
} }
} }