928bcc8d3a
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: 09943450 Update SnakeYAML version 5515734f SPIGOT-7162: Incorrect description for Entity#getVehicle javadoc 6f82b381 PR-788: Add getHand() to all relevant events CraftBukkit Changes: aaf484f6f SPIGOT-7163: CraftMerchantRecipe doesn't copy demand and specialPrice from BukkitMerchantRecipe 5329dd6fd PR-1107: Add getHand() to all relevant events 93061706e SPIGOT-7045: Ocelots never spawn with babies with spawn reason OCELOT_BABY
86 lines
5.1 KiB
Diff
86 lines
5.1 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 cf809eda2a3feb6abccf7286068280f430452135..4b54af83ef8fd18696d2d21ed52b61f13bff7988 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 0db641f5d5e1293b236ad0d2e3a156802ffed839..064c758b19bc8c9a4e94769dd205a1bdcc972a89 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;
|
|
@@ -123,7 +123,7 @@ public final class PluginClassLoader extends URLClassLoader { // Spigot
|
|
|
|
if (checkGlobal) {
|
|
// This ignores the libraries of other plugins, unless they are transitive dependencies.
|
|
- Class<?> result = loader.getClassByName(name, resolve, description);
|
|
+ Class<?> result = loader.getClassByName(name, resolve, description, this); // Paper - prioritize self
|
|
|
|
if (result != null) {
|
|
// If the class was loaded from a library instead of a PluginClassLoader, we can assume that its associated plugin is a transitive dependency and can therefore skip this check.
|