PaperMC/Spigot-API-Patches/0205-Prioritise-own-classes-where-possible.patch
Jake Potrebic cb896d4710
Updated Upstream (Bukkit/CraftBukkit/Spigot) (#5643)
Upstream has released updates that appear to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

Bukkit Changes:
146a7e4b SPIGOT-5345: Add automatic library support

CraftBukkit Changes:
b1064c69 Remove sisu annotation processor from jar
32e40866 SPIGOT-6189: Persistent data disappears when calling setFacingDirection on an item frame
d189f78b # 827: Trigger vanilla dimension advancements in non-main worlds
5bbb4a65 Add plumbing for automatic library support

Spigot Changes:
9fb885e8 Rebuild patches
2021-05-15 22:52:07 +00:00

86 lines
4.9 KiB
Diff

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.
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
index ce751577623eaad0f31e2eb7bf0842d1ab73e845..31793f46e5623729dfb4048e901f274082f57826 100644
--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
@@ -51,6 +51,7 @@ import org.yaml.snakeyaml.error.YAMLException;
*/
public final class JavaPluginLoader implements PluginLoader {
final Server server;
+ private static final boolean DISABLE_CLASS_PRIORITIZATION = Boolean.getBoolean("Paper.DisableClassPrioritization"); // Paper
private final Pattern[] fileFilters = new Pattern[]{Pattern.compile("\\.jar$")};
private final Map<String, java.util.concurrent.locks.ReentrantReadWriteLock> classLoadLock = new java.util.HashMap<String, java.util.concurrent.locks.ReentrantReadWriteLock>(); // Paper
private final Map<String, Integer> classLoadLockCount = new java.util.HashMap<String, Integer>(); // Paper
@@ -203,6 +204,11 @@ public final class JavaPluginLoader implements PluginLoader {
@Nullable
Class<?> getClassByName(final String name, boolean resolve, PluginDescriptionFile description) {
+ // Paper start - prioritize self
+ return getClassByName(name, resolve, description, null);
+ }
+ Class<?> getClassByName(final String name, boolean resolve, PluginDescriptionFile description, PluginClassLoader requester) {
+ // Paper end
// Paper start - make MT safe
java.util.concurrent.locks.ReentrantReadWriteLock lock;
synchronized (classLoadLock) {
@@ -210,6 +216,13 @@ 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 {
+ return requester.loadClass0(name, false, false, ((SimplePluginManager) server.getPluginManager()).isTransitiveDepend(description, requester.getDescription()));
+ } catch (ClassNotFoundException cnfe) {}
+ }
+ // Paper end
// Paper end
for (PluginClassLoader loader : loaders) {
try {
diff --git a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
index 22abd85da592c79e312928de596e5d552a45ef12..cfa408e560d85311b474562a6d3860363727eff0 100644
--- a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
+++ b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
@@ -33,7 +33,7 @@ public final class PluginClassLoader extends URLClassLoader { // Spigot
public JavaPlugin getPlugin() { return plugin; } // Spigot
private final JavaPluginLoader loader;
private final Map<String, Class<?>> classes = new ConcurrentHashMap<String, Class<?>>();
- private final PluginDescriptionFile description;
+ private final PluginDescriptionFile description; PluginDescriptionFile getDescription() { return description; } // Paper
private final File dataFolder;
private final File file;
private final JarFile jar;
@@ -117,7 +117,7 @@ public final class PluginClassLoader extends URLClassLoader { // Spigot
}
if (checkGlobal) {
- Class<?> result = loader.getClassByName(name, resolve, description);
+ Class<?> result = loader.getClassByName(name, resolve, description, this); // Paper - prioritize self
if (result != null) {
PluginDescriptionFile provider = ((PluginClassLoader) result.getClassLoader()).description;