Correctly Remove Classloaders, Avoid Loading Providers in /paper dumpplugins, Fix library lookup (#8938)

This commit is contained in:
Owen 2023-03-06 19:20:11 -05:00 committed by GitHub
parent bf2053a156
commit 4d7269e07c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 119 additions and 63 deletions

View file

@ -904,10 +904,10 @@ index 0000000000000000000000000000000000000000..64e46fdfa4d404cb08c67a456e5990b7
+}
diff --git a/src/main/java/io/papermc/paper/plugin/provider/classloader/ConfiguredPluginClassLoader.java b/src/main/java/io/papermc/paper/plugin/provider/classloader/ConfiguredPluginClassLoader.java
new file mode 100644
index 0000000000000000000000000000000000000000..ab1fb50912e411e708ba1e40303b1c08dabb086d
index 0000000000000000000000000000000000000000..a21bdc57564aef7caf43dde3b2bcb2fc7f30461c
--- /dev/null
+++ b/src/main/java/io/papermc/paper/plugin/provider/classloader/ConfiguredPluginClassLoader.java
@@ -0,0 +1,63 @@
@@ -0,0 +1,71 @@
+package io.papermc.paper.plugin.provider.classloader;
+
+import io.papermc.paper.plugin.configuration.PluginMeta;
@ -970,6 +970,14 @@ index 0000000000000000000000000000000000000000..ab1fb50912e411e708ba1e40303b1c08
+ * @return the plugin or null if it doesn't exist yet
+ */
+ @Nullable JavaPlugin getPlugin();
+
+ /**
+ * Get the plugin classloader group
+ * that is used by the underlying classloader
+ * @return classloader
+ */
+ @Nullable
+ PluginClassLoaderGroup getGroup();
+}
diff --git a/src/main/java/io/papermc/paper/plugin/provider/classloader/PaperClassLoaderStorage.java b/src/main/java/io/papermc/paper/plugin/provider/classloader/PaperClassLoaderStorage.java
new file mode 100644
@ -1969,7 +1977,7 @@ index 669a70faa95d0d6525a731d73499ed6fb0b48320..c9cf9d361a1289aba383718733a2098b
throw new IllegalStateException("Cannot get plugin for " + clazz + " from a static initializer");
}
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
index 047c0304fd617cec990f80815b43916c6ef5a94c..d0ad072c832b8fc8a1cfdcafdd42c724531a2e29 100644
index 047c0304fd617cec990f80815b43916c6ef5a94c..ab04ffe4cd05315a2ee0f64c553b4c674740eb7f 100644
--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
@@ -49,6 +49,7 @@ import org.yaml.snakeyaml.error.YAMLException;
@ -1993,7 +2001,7 @@ index 047c0304fd617cec990f80815b43916c6ef5a94c..d0ad072c832b8fc8a1cfdcafdd42c724
final PluginClassLoader loader;
try {
- loader = new PluginClassLoader(this, getClass().getClassLoader(), description, dataFolder, file, (libraryLoader != null) ? libraryLoader.createLoader(description) : null);
+ loader = new PluginClassLoader(getClass().getClassLoader(), description, dataFolder, file, (libraryLoader != null) ? libraryLoader.createLoader(description) : null, null); // Paper
+ loader = new PluginClassLoader(getClass().getClassLoader(), description, dataFolder, file, (libraryLoader != null) ? libraryLoader.createLoader(description) : null, null, null); // Paper
} catch (InvalidPluginException ex) {
throw ex;
} catch (Throwable ex) {
@ -2032,7 +2040,7 @@ index 6d634b0ea813ccb19f1562a7d0e5a59cea4eab21..e4b6f278a811acbb0070e311c5c3bdaf
}
diff --git a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
index 2f74ec96ece706de23156ebabfe493211bc05391..c42663a2ae98fda6dcf2ab6ac899cc6238bce65f 100644
index 2f74ec96ece706de23156ebabfe493211bc05391..2d2fa6ce5200eb5c75a733f9f54f400113cc22b0 100644
--- a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
+++ b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
@@ -29,7 +29,8 @@ import org.jetbrains.annotations.Nullable;
@ -2045,12 +2053,13 @@ index 2f74ec96ece706de23156ebabfe493211bc05391..c42663a2ae98fda6dcf2ab6ac899cc62
private final JavaPluginLoader loader;
private final Map<String, Class<?>> classes = new ConcurrentHashMap<String, Class<?>>();
private final PluginDescriptionFile description;
@@ -43,24 +44,30 @@ final class PluginClassLoader extends URLClassLoader {
@@ -43,24 +44,32 @@ final class PluginClassLoader extends URLClassLoader {
private JavaPlugin pluginInit;
private IllegalStateException pluginState;
private final Set<String> seenIllegalAccess = Collections.newSetFromMap(new ConcurrentHashMap<>());
+ private java.util.logging.Logger logger; // Paper - add field
+ private io.papermc.paper.plugin.provider.classloader.PluginClassLoaderGroup classLoaderGroup; // Paper
+ public io.papermc.paper.plugin.provider.entrypoint.DependencyContext dependencyContext; // Paper
static {
ClassLoader.registerAsParallelCapable();
@ -2058,7 +2067,7 @@ index 2f74ec96ece706de23156ebabfe493211bc05391..c42663a2ae98fda6dcf2ab6ac899cc62
- PluginClassLoader(@NotNull final JavaPluginLoader loader, @Nullable final ClassLoader parent, @NotNull final PluginDescriptionFile description, @NotNull final File dataFolder, @NotNull final File file, @Nullable ClassLoader libraryLoader) throws IOException, InvalidPluginException, MalformedURLException {
+ @org.jetbrains.annotations.ApiStatus.Internal // Paper
+ public PluginClassLoader(@Nullable final ClassLoader parent, @NotNull final PluginDescriptionFile description, @NotNull final File dataFolder, @NotNull final File file, @Nullable ClassLoader libraryLoader, @Nullable JarFile jarFile) throws IOException, InvalidPluginException, MalformedURLException { // Paper // Paper - use JarFile provided by SpigotPluginProvider
+ public PluginClassLoader(@Nullable final ClassLoader parent, @NotNull final PluginDescriptionFile description, @NotNull final File dataFolder, @NotNull final File file, @Nullable ClassLoader libraryLoader, @Nullable JarFile jarFile, io.papermc.paper.plugin.provider.entrypoint.DependencyContext dependencyContext) throws IOException, InvalidPluginException, MalformedURLException { // Paper // Paper - use JarFile provided by SpigotPluginProvider
super(new URL[] {file.toURI().toURL()}, parent);
- Preconditions.checkArgument(loader != null, "Loader cannot be null");
+ this.loader = null; // Paper - pass null into loader field
@ -2075,12 +2084,13 @@ index 2f74ec96ece706de23156ebabfe493211bc05391..c42663a2ae98fda6dcf2ab6ac899cc62
+
+ // Paper start
+ this.classLoaderGroup = io.papermc.paper.plugin.provider.classloader.PaperClassLoaderStorage.instance().registerSpigotGroup(this); // Paper
+ this.dependencyContext = dependencyContext;
+ this.classLoaderGroup = io.papermc.paper.plugin.provider.classloader.PaperClassLoaderStorage.instance().registerSpigotGroup(this);
+ // Paper end
try {
Class<?> jarClass;
try {
@@ -94,6 +101,27 @@ final class PluginClassLoader extends URLClassLoader {
@@ -94,6 +103,27 @@ final class PluginClassLoader extends URLClassLoader {
return findResources(name);
}
@ -2108,7 +2118,7 @@ index 2f74ec96ece706de23156ebabfe493211bc05391..c42663a2ae98fda6dcf2ab6ac899cc62
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
return loadClass0(name, resolve, true, true);
@@ -119,26 +147,11 @@ final class PluginClassLoader extends URLClassLoader {
@@ -119,26 +149,11 @@ final class PluginClassLoader extends URLClassLoader {
if (checkGlobal) {
// This ignores the libraries of other plugins, unless they are transitive dependencies.
@ -2137,7 +2147,7 @@ index 2f74ec96ece706de23156ebabfe493211bc05391..c42663a2ae98fda6dcf2ab6ac899cc62
return result;
}
@@ -167,7 +180,7 @@ final class PluginClassLoader extends URLClassLoader {
@@ -167,7 +182,7 @@ final class PluginClassLoader extends URLClassLoader {
throw new ClassNotFoundException(name, ex);
}
@ -2146,7 +2156,7 @@ index 2f74ec96ece706de23156ebabfe493211bc05391..c42663a2ae98fda6dcf2ab6ac899cc62
int dot = name.lastIndexOf('.');
if (dot != -1) {
@@ -197,8 +210,8 @@ final class PluginClassLoader extends URLClassLoader {
@@ -197,8 +212,8 @@ final class PluginClassLoader extends URLClassLoader {
result = super.findClass(name);
}
@ -2156,7 +2166,7 @@ index 2f74ec96ece706de23156ebabfe493211bc05391..c42663a2ae98fda6dcf2ab6ac899cc62
}
return result;
@@ -207,6 +220,12 @@ final class PluginClassLoader extends URLClassLoader {
@@ -207,6 +222,12 @@ final class PluginClassLoader extends URLClassLoader {
@Override
public void close() throws IOException {
try {
@ -2169,7 +2179,7 @@ index 2f74ec96ece706de23156ebabfe493211bc05391..c42663a2ae98fda6dcf2ab6ac899cc62
super.close();
} finally {
jar.close();
@@ -218,7 +237,7 @@ final class PluginClassLoader extends URLClassLoader {
@@ -218,7 +239,7 @@ final class PluginClassLoader extends URLClassLoader {
return classes.values();
}
@ -2178,7 +2188,7 @@ index 2f74ec96ece706de23156ebabfe493211bc05391..c42663a2ae98fda6dcf2ab6ac899cc62
Preconditions.checkArgument(javaPlugin != null, "Initializing plugin cannot be null");
Preconditions.checkArgument(javaPlugin.getClass().getClassLoader() == this, "Cannot initialize plugin outside of this class loader");
if (this.plugin != null || this.pluginInit != null) {
@@ -228,6 +247,32 @@ final class PluginClassLoader extends URLClassLoader {
@@ -228,6 +249,38 @@ final class PluginClassLoader extends URLClassLoader {
pluginState = new IllegalStateException("Initial initialization");
this.pluginInit = javaPlugin;
@ -2210,6 +2220,12 @@ index 2f74ec96ece706de23156ebabfe493211bc05391..c42663a2ae98fda6dcf2ab6ac899cc62
+ org.bukkit.configuration.serialization.ConfigurationSerialization.unregisterClass(serializable);
+ }
}
+
+ @Override
+ public @Nullable io.papermc.paper.plugin.provider.classloader.PluginClassLoaderGroup getGroup() {
+ return this.classLoaderGroup;
+ }
+
+ // Paper end
}
diff --git a/src/test/java/io/papermc/paper/testing/TestServer.java b/src/test/java/io/papermc/paper/testing/TestServer.java