From 4d7269e07cf152cd25943a17eaf1ced790bbb8ce Mon Sep 17 00:00:00 2001 From: Owen <23108066+Owen1212055@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:20:11 -0500 Subject: [PATCH] Correctly Remove Classloaders, Avoid Loading Providers in /paper dumpplugins, Fix library lookup (#8938) --- patches/api/0008-Paper-Plugins.patch | 46 ++++--- ...or-plugins-modifying-the-parent-of-t.patch | 10 +- ...231-Enable-multi-release-plugin-jars.patch | 4 +- ...s-to-contain-the-source-jars-in-stac.patch | 6 +- ...so-load-resources-from-LibraryLoader.patch | 4 +- patches/server/0013-Paper-Plugins.patch | 112 ++++++++++++------ 6 files changed, 119 insertions(+), 63 deletions(-) diff --git a/patches/api/0008-Paper-Plugins.patch b/patches/api/0008-Paper-Plugins.patch index 5bd6d47af5..7bdf5ebe9b 100644 --- a/patches/api/0008-Paper-Plugins.patch +++ b/patches/api/0008-Paper-Plugins.patch @@ -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> classes = new ConcurrentHashMap>(); 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 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 diff --git a/patches/api/0072-Add-workaround-for-plugins-modifying-the-parent-of-t.patch b/patches/api/0072-Add-workaround-for-plugins-modifying-the-parent-of-t.patch index 6872c59455..323ce99c80 100644 --- a/patches/api/0072-Add-workaround-for-plugins-modifying-the-parent-of-t.patch +++ b/patches/api/0072-Add-workaround-for-plugins-modifying-the-parent-of-t.patch @@ -93,19 +93,19 @@ index 71c8d2345eef6895edb8d210553ec3cddd9c76d0..6d31f3a2569ae9c522a5e6cddd38ac8f /** diff --git a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java -index c42663a2ae98fda6dcf2ab6ac899cc6238bce65f..ed2492ce51097dd0c2ba72e7b9449561a73ea7e3 100644 +index 2f045068c34c7c007565b7d7a17b7a003a79f37b..805f2bef4a785cb9639afd40ef820452efd1b2cf 100644 --- a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java +++ b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java -@@ -64,7 +64,7 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm +@@ -65,7 +65,7 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm this.url = file.toURI().toURL(); this.libraryLoader = libraryLoader; - + this.logger = com.destroystokyo.paper.utils.PaperPluginLogger.getLogger(description); // Paper - Register logger early // Paper start - this.classLoaderGroup = io.papermc.paper.plugin.provider.classloader.PaperClassLoaderStorage.instance().registerSpigotGroup(this); // Paper - // Paper end -@@ -247,6 +247,7 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm + this.dependencyContext = dependencyContext; + this.classLoaderGroup = io.papermc.paper.plugin.provider.classloader.PaperClassLoaderStorage.instance().registerSpigotGroup(this); +@@ -249,6 +249,7 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm pluginState = new IllegalStateException("Initial initialization"); this.pluginInit = javaPlugin; diff --git a/patches/api/0231-Enable-multi-release-plugin-jars.patch b/patches/api/0231-Enable-multi-release-plugin-jars.patch index b7365d8e33..0cb56eea52 100644 --- a/patches/api/0231-Enable-multi-release-plugin-jars.patch +++ b/patches/api/0231-Enable-multi-release-plugin-jars.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Enable multi-release plugin jars diff --git a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java -index ed2492ce51097dd0c2ba72e7b9449561a73ea7e3..9c409dcd0179bea236311e1d5998daa4245e1542 100644 +index 805f2bef4a785cb9639afd40ef820452efd1b2cf..caffe498ef5abf09944f846bf5a958b10de514df 100644 --- a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java +++ b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java -@@ -59,7 +59,7 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm +@@ -60,7 +60,7 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm this.description = description; this.dataFolder = dataFolder; this.file = file; diff --git a/patches/api/0309-Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch b/patches/api/0309-Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch index 5d02646a56..fc55c97c46 100644 --- a/patches/api/0309-Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch +++ b/patches/api/0309-Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch @@ -5,13 +5,13 @@ Subject: [PATCH] Rewrite LogEvents to contain the source jars in stack traces diff --git a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java -index 9c409dcd0179bea236311e1d5998daa4245e1542..bfc4a97f1fb0d245056598d5211ff2347a431b64 100644 +index caffe498ef5abf09944f846bf5a958b10de514df..b3429d739c74d8b6b692a47ab49b0f0de1e5ea8f 100644 --- a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java +++ b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java -@@ -53,7 +53,7 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm +@@ -54,7 +54,7 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm @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); + super(file.getName(), new URL[] {file.toURI().toURL()}, parent); this.loader = null; // Paper - pass null into loader field diff --git a/patches/api/0382-Also-load-resources-from-LibraryLoader.patch b/patches/api/0382-Also-load-resources-from-LibraryLoader.patch index a853b8bb17..e007a908a8 100644 --- a/patches/api/0382-Also-load-resources-from-LibraryLoader.patch +++ b/patches/api/0382-Also-load-resources-from-LibraryLoader.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Also load resources from LibraryLoader diff --git a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java -index bfc4a97f1fb0d245056598d5211ff2347a431b64..e89ab347b908cc92274dd5dd796a02249f899977 100644 +index b3429d739c74d8b6b692a47ab49b0f0de1e5ea8f..526d313d0922c0c1ce9fbfad14e0bfa1fe86caf2 100644 --- a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java +++ b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java -@@ -93,14 +93,35 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm +@@ -95,14 +95,35 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm @Override public URL getResource(String name) { diff --git a/patches/server/0013-Paper-Plugins.patch b/patches/server/0013-Paper-Plugins.patch index 4c0e92b96c..362e6d903d 100644 --- a/patches/server/0013-Paper-Plugins.patch +++ b/patches/server/0013-Paper-Plugins.patch @@ -258,10 +258,10 @@ index 0000000000000000000000000000000000000000..f0fce4113fb07c64adbec029d177c236 +} diff --git a/src/main/java/io/papermc/paper/command/subcommands/DumpPluginsCommand.java b/src/main/java/io/papermc/paper/command/subcommands/DumpPluginsCommand.java new file mode 100644 -index 0000000000000000000000000000000000000000..4ecd00b32c7abc15d655dd3c999b6feca332c3a1 +index 0000000000000000000000000000000000000000..7159c72408f556d676eded668057a4c5ebb21719 --- /dev/null +++ b/src/main/java/io/papermc/paper/command/subcommands/DumpPluginsCommand.java -@@ -0,0 +1,187 @@ +@@ -0,0 +1,200 @@ +package io.papermc.paper.command.subcommands; + +import com.google.gson.JsonArray; @@ -276,6 +276,8 @@ index 0000000000000000000000000000000000000000..4ecd00b32c7abc15d655dd3c999b6fec +import io.papermc.paper.plugin.entrypoint.classloader.group.LockingClassLoaderGroup; +import io.papermc.paper.plugin.entrypoint.classloader.group.PaperPluginClassLoaderStorage; +import io.papermc.paper.plugin.entrypoint.classloader.group.SimpleListPluginClassLoaderGroup; ++import io.papermc.paper.plugin.entrypoint.classloader.group.SpigotPluginClassLoaderGroup; ++import io.papermc.paper.plugin.entrypoint.classloader.group.StaticPluginClassLoaderGroup; +import io.papermc.paper.plugin.provider.entrypoint.DependencyContext; +import io.papermc.paper.plugin.entrypoint.strategy.ModernPluginLoadingStrategy; +import io.papermc.paper.plugin.entrypoint.strategy.ProviderConfiguration; @@ -390,10 +392,15 @@ index 0000000000000000000000000000000000000000..4ecd00b32c7abc15d655dd3c999b6fec + + @Override + public boolean load(PluginProvider provider, Object provided) { ++ return true; ++ } ++ ++ @Override ++ public boolean preloadProvider(PluginProvider provider) { ++ // Don't load provider + loadOrder.add(provider.getMeta().getName()); + return false; + } -+ + }); + modernPluginLoadingStrategy.loadProviders(pluginProviders); + @@ -430,6 +437,12 @@ index 0000000000000000000000000000000000000000..4ecd00b32c7abc15d655dd3c999b6fec + if (group instanceof SimpleListPluginClassLoaderGroup listGroup) { + JsonArray array = new JsonArray(); + classLoadersRoot.addProperty("main", listGroup.toString()); ++ if (group instanceof StaticPluginClassLoaderGroup staticPluginClassLoaderGroup) { ++ classLoadersRoot.addProperty("plugin-holder", staticPluginClassLoaderGroup.getPluginClassloader().toString()); ++ } else if (group instanceof SpigotPluginClassLoaderGroup spigotPluginClassLoaderGroup) { ++ classLoadersRoot.addProperty("plugin-holder", spigotPluginClassLoaderGroup.getPluginClassLoader().toString()); ++ } ++ + classLoadersRoot.add("children", array); + for (ConfiguredPluginClassLoader innerGroup : listGroup.getClassLoaders()) { + array.add(this.writeClassloader(innerGroup)); @@ -803,10 +816,10 @@ index 0000000000000000000000000000000000000000..f9a2c55a354c877749db3f92956de802 +} diff --git a/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/PaperPluginClassLoader.java b/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/PaperPluginClassLoader.java new file mode 100644 -index 0000000000000000000000000000000000000000..79581d917e754998123b94b9f4ea7d1e78f017ae +index 0000000000000000000000000000000000000000..ecd11d3bd6c7e80a9b33cb8c2d7ed8a582857533 --- /dev/null +++ b/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/PaperPluginClassLoader.java -@@ -0,0 +1,202 @@ +@@ -0,0 +1,207 @@ +package io.papermc.paper.plugin.entrypoint.classloader; + +import io.papermc.paper.plugin.configuration.PluginMeta; @@ -1008,6 +1021,11 @@ index 0000000000000000000000000000000000000000..79581d917e754998123b94b9f4ea7d1e + super.close(); + } + } ++ ++ @Override ++ public @Nullable PluginClassLoaderGroup getGroup() { ++ return this.group; ++ } +} diff --git a/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/PaperSimplePluginClassLoader.java b/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/PaperSimplePluginClassLoader.java new file mode 100644 @@ -1186,7 +1204,7 @@ index 0000000000000000000000000000000000000000..eaf5c794cbe8d6138c9d60eaae20f5fc +} diff --git a/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/group/GlobalPluginClassLoaderGroup.java b/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/group/GlobalPluginClassLoaderGroup.java new file mode 100644 -index 0000000000000000000000000000000000000000..2b7eef787f83e5a32896cb30c215406b6f652786 +index 0000000000000000000000000000000000000000..2a4933088928a51c8135a3a60b7447d9d10c66c4 --- /dev/null +++ b/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/group/GlobalPluginClassLoaderGroup.java @@ -0,0 +1,18 @@ @@ -1205,7 +1223,7 @@ index 0000000000000000000000000000000000000000..2b7eef787f83e5a32896cb30c215406b + + @Override + public String toString() { -+ return super.toString(); ++ return "GLOBAL:" + super.toString(); + } +} diff --git a/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/group/LockingClassLoaderGroup.java b/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/group/LockingClassLoaderGroup.java @@ -1292,7 +1310,7 @@ index 0000000000000000000000000000000000000000..aae50ebba6ba1579b75af5370c8b020d +} diff --git a/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/group/PaperPluginClassLoaderStorage.java b/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/group/PaperPluginClassLoaderStorage.java new file mode 100644 -index 0000000000000000000000000000000000000000..2c906e2c7d972b221a41acd614e00d0fbc1227c6 +index 0000000000000000000000000000000000000000..e6fcdeb96356ff4713627b1458ac8bbfad1866b1 --- /dev/null +++ b/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/group/PaperPluginClassLoaderStorage.java @@ -0,0 +1,93 @@ @@ -1302,7 +1320,6 @@ index 0000000000000000000000000000000000000000..2c906e2c7d972b221a41acd614e00d0f +import io.papermc.paper.plugin.provider.classloader.ConfiguredPluginClassLoader; +import io.papermc.paper.plugin.provider.classloader.PaperClassLoaderStorage; +import io.papermc.paper.plugin.provider.classloader.PluginClassLoaderGroup; -+import org.bukkit.Bukkit; +import org.bukkit.plugin.java.PluginClassLoader; +import org.jetbrains.annotations.ApiStatus; + @@ -1325,8 +1342,8 @@ index 0000000000000000000000000000000000000000..2c906e2c7d972b221a41acd614e00d0f + @Override + public PluginClassLoaderGroup registerSpigotGroup(PluginClassLoader pluginClassLoader) { + return this.registerGroup(pluginClassLoader, new SpigotPluginClassLoaderGroup(this.globalGroup, (library) -> { -+ return Bukkit.getServer().getPluginManager().isTransitiveDependency(pluginClassLoader.getConfiguration(), library.getConfiguration()); -+ })); ++ return pluginClassLoader.dependencyContext.isTransitiveDependency(pluginClassLoader.getConfiguration(), library.getConfiguration()); ++ }, pluginClassLoader)); + } + + @Override @@ -1343,7 +1360,7 @@ index 0000000000000000000000000000000000000000..2c906e2c7d972b221a41acd614e00d0f + } + } + -+ return this.registerGroup(classLoader, new StaticPluginClassLoaderGroup(allowedLoaders, access)); ++ return this.registerGroup(classLoader, new StaticPluginClassLoaderGroup(allowedLoaders, access, classLoader)); + } + + private PluginClassLoaderGroup registerGroup(ConfiguredPluginClassLoader classLoader, PluginClassLoaderGroup group) { @@ -1362,6 +1379,7 @@ index 0000000000000000000000000000000000000000..2c906e2c7d972b221a41acd614e00d0f + @Override + public void unregisterClassloader(ConfiguredPluginClassLoader configuredPluginClassLoader) { + this.globalGroup.remove(configuredPluginClassLoader); ++ this.groups.remove(configuredPluginClassLoader.getGroup()); + for (PluginClassLoaderGroup group : this.groups) { + group.remove(configuredPluginClassLoader); + } @@ -1372,7 +1390,7 @@ index 0000000000000000000000000000000000000000..2c906e2c7d972b221a41acd614e00d0f + if (this.globalGroup.getClassLoaders().contains(pluginLoader)) { + return false; + } else { -+ this.globalGroup.getClassLoaders().add(pluginLoader); ++ this.globalGroup.add(pluginLoader); + return true; + } + } @@ -1532,14 +1550,15 @@ index 0000000000000000000000000000000000000000..3b670bd6b35ae7f56488a9b50df54709 +} diff --git a/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/group/SpigotPluginClassLoaderGroup.java b/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/group/SpigotPluginClassLoaderGroup.java new file mode 100644 -index 0000000000000000000000000000000000000000..5d26367524389388be163ae3120c1d2bf55cfef7 +index 0000000000000000000000000000000000000000..5a9f5b18e24a89dd642149a7a3d49390328b864b --- /dev/null +++ b/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/group/SpigotPluginClassLoaderGroup.java -@@ -0,0 +1,49 @@ +@@ -0,0 +1,58 @@ +package io.papermc.paper.plugin.entrypoint.classloader.group; + +import io.papermc.paper.plugin.provider.classloader.ClassLoaderAccess; +import io.papermc.paper.plugin.provider.classloader.ConfiguredPluginClassLoader; ++import org.bukkit.plugin.java.PluginClassLoader; +import org.jetbrains.annotations.ApiStatus; + +import java.util.function.Predicate; @@ -1552,10 +1571,12 @@ index 0000000000000000000000000000000000000000..5d26367524389388be163ae3120c1d2b +public class SpigotPluginClassLoaderGroup extends SimpleListPluginClassLoaderGroup { + + private final Predicate libraryClassloaderPredicate; ++ private final PluginClassLoader pluginClassLoader; + -+ public SpigotPluginClassLoaderGroup(GlobalPluginClassLoaderGroup globalPluginClassLoaderGroup, Predicate libraryClassloaderPredicate) { ++ public SpigotPluginClassLoaderGroup(GlobalPluginClassLoaderGroup globalPluginClassLoaderGroup, Predicate libraryClassloaderPredicate, PluginClassLoader pluginClassLoader) { + super(globalPluginClassLoaderGroup.getClassLoaders()); + this.libraryClassloaderPredicate = libraryClassloaderPredicate; ++ this.pluginClassLoader = pluginClassLoader; + } + + // Mirrors global list @@ -1567,14 +1588,20 @@ index 0000000000000000000000000000000000000000..5d26367524389388be163ae3120c1d2b + public void remove(ConfiguredPluginClassLoader configuredPluginClassLoader) { + } + ++ // Don't allow other plugins to access spigot dependencies, they should instead reference the global list ++ @Override ++ public ClassLoaderAccess getAccess() { ++ return v -> false; ++ } ++ + @Override + protected Class lookupClass(String name, boolean resolve, ConfiguredPluginClassLoader current) throws ClassNotFoundException { + return current.loadClass(name, resolve, false, this.libraryClassloaderPredicate.test(current)); + } + -+ @Override -+ public ClassLoaderAccess getAccess() { -+ return v -> true; ++ // DEBUG ++ public PluginClassLoader getPluginClassLoader() { ++ return pluginClassLoader; + } + + @Override @@ -1587,10 +1614,10 @@ index 0000000000000000000000000000000000000000..5d26367524389388be163ae3120c1d2b +} diff --git a/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/group/StaticPluginClassLoaderGroup.java b/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/group/StaticPluginClassLoaderGroup.java new file mode 100644 -index 0000000000000000000000000000000000000000..7f7085b06271adf8a37485f4c9c9b8af605dd27d +index 0000000000000000000000000000000000000000..2412155ddfd559023f42ff534b8f06a52588e1e0 --- /dev/null +++ b/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/group/StaticPluginClassLoaderGroup.java -@@ -0,0 +1,31 @@ +@@ -0,0 +1,40 @@ +package io.papermc.paper.plugin.entrypoint.classloader.group; + +import io.papermc.paper.plugin.provider.classloader.ClassLoaderAccess; @@ -1603,10 +1630,13 @@ index 0000000000000000000000000000000000000000..7f7085b06271adf8a37485f4c9c9b8af +public class StaticPluginClassLoaderGroup extends SimpleListPluginClassLoaderGroup { + + private final ClassLoaderAccess access; ++ // Debug only ++ private final ConfiguredPluginClassLoader mainClassloaderHolder; + -+ public StaticPluginClassLoaderGroup(List classloaders, ClassLoaderAccess access) { ++ public StaticPluginClassLoaderGroup(List classloaders, ClassLoaderAccess access, ConfiguredPluginClassLoader mainClassloaderHolder) { + super(classloaders); + this.access = access; ++ this.mainClassloaderHolder = mainClassloaderHolder; + } + + @Override @@ -1614,6 +1644,12 @@ index 0000000000000000000000000000000000000000..7f7085b06271adf8a37485f4c9c9b8af + return this.access; + } + ++ // DEBUG ++ @ApiStatus.Internal ++ public ConfiguredPluginClassLoader getPluginClassloader() { ++ return this.mainClassloaderHolder; ++ } ++ + @Override + public String toString() { + return "StaticPluginClassLoaderGroup{" + @@ -2404,10 +2440,10 @@ index 0000000000000000000000000000000000000000..779f6980a71db8df68c9cf2078497640 +} diff --git a/src/main/java/io/papermc/paper/plugin/entrypoint/strategy/ModernPluginLoadingStrategy.java b/src/main/java/io/papermc/paper/plugin/entrypoint/strategy/ModernPluginLoadingStrategy.java new file mode 100644 -index 0000000000000000000000000000000000000000..671e9ebb8246a4cc9e212f5b11ea476560f2f7d5 +index 0000000000000000000000000000000000000000..1d58f3a438d5be423c84b2f61e496d938fdc2995 --- /dev/null +++ b/src/main/java/io/papermc/paper/plugin/entrypoint/strategy/ModernPluginLoadingStrategy.java -@@ -0,0 +1,209 @@ +@@ -0,0 +1,211 @@ +package io.papermc.paper.plugin.entrypoint.strategy; + +import com.google.common.collect.Lists; @@ -2556,9 +2592,11 @@ index 0000000000000000000000000000000000000000..671e9ebb8246a4cc9e212f5b11ea4765 + try { + this.configuration.applyContext(retrievedProvider, graphDependencyContext); + -+ T instance = retrievedProvider.createInstance(); -+ if (this.configuration.load(retrievedProvider, instance)) { -+ loadedPlugins.add(new ProviderPair<>(retrievedProvider, instance)); ++ if (this.configuration.preloadProvider(retrievedProvider)) { ++ T instance = retrievedProvider.createInstance(); ++ if (this.configuration.load(retrievedProvider, instance)) { ++ loadedPlugins.add(new ProviderPair<>(retrievedProvider, instance)); ++ } + } + } catch (Throwable ex) { + LOGGER.error("Could not load plugin '%s' in folder '%s'".formatted(retrievedProvider.getFileName(), retrievedProvider.getParentSource()), ex); // Paper @@ -2644,17 +2682,15 @@ index 0000000000000000000000000000000000000000..2ea978ac957849260e7ca69c9ff56588 +} diff --git a/src/main/java/io/papermc/paper/plugin/entrypoint/strategy/ProviderConfiguration.java b/src/main/java/io/papermc/paper/plugin/entrypoint/strategy/ProviderConfiguration.java new file mode 100644 -index 0000000000000000000000000000000000000000..71536981075095ee06234c638c0dfa054e737fb8 +index 0000000000000000000000000000000000000000..2c7a0751e5c8d0d1e42f7e245ba09815d4f6f8ff --- /dev/null +++ b/src/main/java/io/papermc/paper/plugin/entrypoint/strategy/ProviderConfiguration.java -@@ -0,0 +1,19 @@ +@@ -0,0 +1,21 @@ +package io.papermc.paper.plugin.entrypoint.strategy; + +import io.papermc.paper.plugin.provider.PluginProvider; +import io.papermc.paper.plugin.provider.entrypoint.DependencyContext; + -+import java.util.List; -+ +/** + * Used to share code with the modern and legacy plugin load strategy. + * @@ -2666,6 +2702,10 @@ index 0000000000000000000000000000000000000000..71536981075095ee06234c638c0dfa05 + + boolean load(PluginProvider provider, T provided); + ++ default boolean preloadProvider(PluginProvider provider) { ++ return true; ++ } ++ +} diff --git a/src/main/java/io/papermc/paper/plugin/entrypoint/strategy/ProviderLoadingStrategy.java b/src/main/java/io/papermc/paper/plugin/entrypoint/strategy/ProviderLoadingStrategy.java new file mode 100644 @@ -4937,7 +4977,7 @@ index 0000000000000000000000000000000000000000..a180612a1ec395202dbae1ca5b97ec01 +} diff --git a/src/main/java/io/papermc/paper/plugin/provider/source/DirectoryProviderSource.java b/src/main/java/io/papermc/paper/plugin/provider/source/DirectoryProviderSource.java new file mode 100644 -index 0000000000000000000000000000000000000000..1822e076601db51c8a7954036853bee1fb8e3704 +index 0000000000000000000000000000000000000000..ed00c412f1703b38674bbd0d483fcb100aa99f9d --- /dev/null +++ b/src/main/java/io/papermc/paper/plugin/provider/source/DirectoryProviderSource.java @@ -0,0 +1,40 @@ @@ -4960,7 +5000,7 @@ index 0000000000000000000000000000000000000000..1822e076601db51c8a7954036853bee1 + private static final Logger LOGGER = LogUtils.getLogger(); + + public DirectoryProviderSource() { -+ super("Directory '%s'"::formatted); ++ super("File '%s'"::formatted); + } + + @Override @@ -5826,6 +5866,7 @@ index 0000000000000000000000000000000000000000..36f8dc31394333bb9aaa9341014037a4 +import com.destroystokyo.paper.util.SneakyThrow; +import com.destroystokyo.paper.utils.PaperPluginLogger; +import io.papermc.paper.plugin.entrypoint.dependency.DependencyUtil; ++import io.papermc.paper.plugin.manager.PaperPluginManagerImpl; +import io.papermc.paper.plugin.provider.configuration.LoadOrderConfiguration; +import io.papermc.paper.plugin.provider.entrypoint.DependencyContext; +import io.papermc.paper.plugin.entrypoint.dependency.DependencyContextHolder; @@ -5942,7 +5983,7 @@ index 0000000000000000000000000000000000000000..36f8dc31394333bb9aaa9341014037a4 + + final PluginClassLoader loader; + try { -+ loader = new PluginClassLoader(this.getClass().getClassLoader(), this.description, dataFolder, this.path.toFile(), LIBRARY_LOADER.createLoader(this.description), this.jarFile); // Paper ++ loader = new PluginClassLoader(this.getClass().getClassLoader(), this.description, dataFolder, this.path.toFile(), LIBRARY_LOADER.createLoader(this.description), this.jarFile, this.dependencyContext); // Paper + } catch (InvalidPluginException ex) { + throw ex; + } catch (Throwable ex) { @@ -5951,8 +5992,7 @@ index 0000000000000000000000000000000000000000..36f8dc31394333bb9aaa9341014037a4 + + // Override dependency context. + // We must provide a temporary context in order to properly handle dependencies on the plugin classloader constructor. -+ // EDIT - Only re add if dependency checking is needed for spigot plugins, but not anymore. -+ // loader.dependencyContext = PaperPluginManagerImpl.getInstance(); ++ loader.dependencyContext = PaperPluginManagerImpl.getInstance(); + + + this.status = ProviderStatus.INITIALIZED;