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 01:18:44 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-27 18:32:30 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 01:18:44 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ import org.yaml.snakeyaml.error.YAMLException;
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-27 18:32:30 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  */
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 01:18:44 -04: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 01:18:44 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     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
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 15:52:07 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     private final Map<String, Integer> classLoadLockCount = new java.util.HashMap<String, Integer>(); // Paper
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 01:18:44 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ public final class JavaPluginLoader implements PluginLoader {
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-27 18:32:30 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 01:18:44 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     @Nullable
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 15:52:07 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     Class<?> getClassByName(final String name, boolean resolve, PluginDescriptionFile description) {
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 01:18:44 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+        // Paper start - prioritize self
 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 15:52:07 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+        return getClassByName(name, resolve, description, null);
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 01:18:44 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+    }
 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 15:52:07 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+    Class<?> getClassByName(final String name, boolean resolve, PluginDescriptionFile description, PluginClassLoader requester) {
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 01:18:44 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+        // Paper end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         // Paper start - make MT safe
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 15:52:07 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								         java.util.concurrent.locks.ReentrantReadWriteLock lock;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         synchronized (classLoadLock) {
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 01:18:44 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ 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 {
 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 15:52:07 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+                return requester.loadClass0(name, false, false, ((SimplePluginManager) server.getPluginManager()).isTransitiveDepend(description, requester.getDescription()));
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 01:18:44 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+                } catch (ClassNotFoundException cnfe) {}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            }
 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 15:52:07 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								+            // Paper end
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 01:18:44 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								         // Paper end
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 15:52:07 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								         for (PluginClassLoader loader : loaders) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             try {
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 01:18:44 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								diff --git a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								--- a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+++ b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-27 18:32:30 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ public final class PluginClassLoader extends URLClassLoader { // Spigot
 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 15:52:07 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     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;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								@@ -0,0 +0,0 @@ public final class PluginClassLoader extends URLClassLoader { // Spigot
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-27 18:32:30 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 15:52:07 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								         if (checkGlobal) {
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 21:35:13 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								             // This ignores the libraries of other plugins, unless they are transitive dependencies.
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 15:52:07 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								-            Class<?> result = loader.getClassByName(name, resolve, description);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								+            Class<?> result = loader.getClassByName(name, resolve, description, this);  // Paper - prioritize self
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-27 18:32:30 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-10 21:35:13 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								             // 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.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             if (result != null && result.getClassLoader() instanceof PluginClassLoader) {