2020-04-27 18:32:30 +02:00
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mariell Hoversholm <proximyst@proximyst.com>
Date: Mon, 27 Apr 2020 12:31:59 +0200
Subject: [PATCH] Prioritise own classes where possible
This adds the server property `Paper.DisableClassPrioritization` to disable
prioritization of own classes for plugins' classloaders.
This value is by default not present, and this will therefore break any
plugins which abuse behaviour related to not using their own classes
while still loading their own. This is often an issue with failing to
relocate or shade properly, such as when shading plugin APIs like Vault.
A plugin's classloader will first look in the same jar as it is loading
in for a requested class, then load it. It does not re-use other
plugins' classes if it has the chance to avoid doing so.
If a class is not found in the same jar as it is loading for and it does
find it elsewhere, it will still choose the class elsewhere. This is
intended behaviour, as it will only prioritise classes it has in its own
jar, no other plugins' classes will be prioritised in any other order
than the one they were registered in.
The patch in general terms just loads the class in the plugin's jar
before it starts looking elsewhere for it.
2020-05-18 07:18:44 +02:00
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
index ba2c5c6eee6fc9f7c96c3ab304d8a1fc759ccd77..528ceeb22c55f23259340c29e3c4ed5ece89a118 100644
--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
@@ -50,6 +50,7 @@ import org.yaml.snakeyaml.error.YAMLException;
2020-04-27 18:32:30 +02:00
*/
2020-05-18 07:18:44 +02:00
public final class JavaPluginLoader implements PluginLoader {
final Server server;
2020-04-27 18:32:30 +02:00
+ private static final boolean DISABLE_CLASS_PRIORITIZATION = Boolean.getBoolean("Paper.DisableClassPrioritization"); // Paper
2020-05-18 07:18:44 +02:00
private final Pattern[] fileFilters = new Pattern[]{Pattern.compile("\\.jar$")};
2020-04-27 18:32:30 +02:00
private final Map<String, Class<?>> classes = new ConcurrentHashMap<String, Class<?>>();
2020-05-18 07:18:44 +02:00
private final Map<String, java.util.concurrent.locks.ReentrantReadWriteLock> classLoadLock = new java.util.HashMap<String, java.util.concurrent.locks.ReentrantReadWriteLock>(); // Paper
@@ -193,6 +194,11 @@ public final class JavaPluginLoader implements PluginLoader {
2020-04-27 18:32:30 +02:00
2020-05-18 07:18:44 +02:00
@Nullable
Class<?> getClassByName(final String name) {
+ // Paper start - prioritize self
+ return getClassByName(name, null);
+ }
+ Class<?> getClassByName(final String name, PluginClassLoader requester) {
+ // Paper end
// Paper start - make MT safe
Class<?> cachedClass = classes.get(name);
if (cachedClass != null) {
@@ -204,6 +210,16 @@ public final class JavaPluginLoader implements PluginLoader {
classLoadLockCount.compute(name, (x, prev) -> prev != null ? prev + 1 : 1);
}
lock.writeLock().lock();try {
+ // Paper start - prioritize self
+ if (!DISABLE_CLASS_PRIORITIZATION && requester != null) {
+ try {
+ cachedClass = requester.findClass(name, false);
+ } catch (ClassNotFoundException cnfe) {}
+ if (cachedClass != null) {
+ return cachedClass;
+ }
+ }
+ // Paper end-
cachedClass = classes.get(name);
// Paper end
2020-04-27 18:32:30 +02:00
2020-05-18 07:18:44 +02:00
diff --git a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
index 3a02dbe9d183bc907dcce081d8338d5716ed5242..28e5c6591fb594ca79ee92480cedc8f549e3fe01 100644
--- a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
+++ b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
@@ -108,7 +108,7 @@ public final class PluginClassLoader extends URLClassLoader { // Spigot
2020-04-27 18:32:30 +02:00
2020-05-18 07:18:44 +02:00
if (result == null) {
if (checkGlobal) {
- result = loader.getClassByName(name);
+ result = loader.getClassByName(name, this); // Paper - prioritize self
2020-04-27 18:32:30 +02:00
2020-05-18 07:18:44 +02:00
if (result != null) {
PluginDescriptionFile provider = ((PluginClassLoader) result.getClassLoader()).description;