From dafcd16a142188af2c4c57caa1733f6fc19fce5a Mon Sep 17 00:00:00 2001 From: NotMyFault Date: Wed, 2 Mar 2022 20:48:49 +0100 Subject: [PATCH] Update Upstream eac5b51 Play dirty because bukkit classloading is bad. (2043) --- .../bukkit/util/ClassSourceValidator.java | 38 +++++++++++++++---- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/sk89q/bukkit/util/ClassSourceValidator.java b/worldedit-bukkit/src/main/java/com/sk89q/bukkit/util/ClassSourceValidator.java index 1b1d59fc0..2ef7fbabb 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/bukkit/util/ClassSourceValidator.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/bukkit/util/ClassSourceValidator.java @@ -25,8 +25,11 @@ 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 javax.annotation.Nullable; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -40,8 +43,20 @@ import static com.google.common.base.Preconditions.checkNotNull; */ 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 @@ -56,6 +71,9 @@ public class ClassSourceValidator { 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."); + } } /** @@ -67,7 +85,7 @@ public class ClassSourceValidator { public Map, Plugin> findMismatches(List> classes) { checkNotNull(classes, "classes"); - if (expectedClassLoader == null) { + if (expectedClassLoader == null || loadClass == null) { return ImmutableMap.of(); } @@ -78,14 +96,18 @@ public class ClassSourceValidator { 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); } } } @@ -139,7 +161,7 @@ public class ClassSourceValidator { 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()); } }