aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJason Penilla <[email protected]>2024-05-23 13:13:02 -0700
committerGitHub <[email protected]>2024-05-23 13:13:02 -0700
commit5e7b65a9a9c0c9f51679933447bfad543fc1e11d (patch)
treecace5ad84656b4e47d5f3cfed44bb1981fdad6d2
parent2a90732677f1e3a6aab16ae039ede5f65d411b8b (diff)
downloadPaper-5e7b65a9a9c0c9f51679933447bfad543fc1e11d.tar.gz
Paper-5e7b65a9a9c0c9f51679933447bfad543fc1e11d.zip
Allow using PluginLoader classpath API from Bukkit plugins (#10758)
Allows using the PluginLoader API without any of the other changes imposed by switching to a paper-plugin.yml. Used by setting paper-plugin-loader in plugin.yml to the class name of your PluginLoader. Also allows skipping the libraries field by setting paper-skip-libraries to true (by default both libraries and jars provided by the PluginLoader are added to the classpath).
-rw-r--r--patches/api/0479-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch91
-rw-r--r--patches/server/0019-Paper-Plugins.patch20
-rw-r--r--patches/server/1047-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch130
3 files changed, 233 insertions, 8 deletions
diff --git a/patches/api/0479-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch b/patches/api/0479-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch
new file mode 100644
index 0000000000..786865aa5f
--- /dev/null
+++ b/patches/api/0479-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch
@@ -0,0 +1,91 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jason Penilla <[email protected]>
+Date: Tue, 21 May 2024 13:18:00 -0700
+Subject: [PATCH] Allow Bukkit plugin to use Paper PluginLoader API
+
+
+diff --git a/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java b/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java
+index c0691a849831f99268fdcb7b0f471f80a1a2a70e..8f45caade7357bc55c6a90cfe0c3a2feb2d877ff 100644
+--- a/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java
++++ b/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java
+@@ -259,6 +259,13 @@ public final class PluginDescriptionFile implements io.papermc.paper.plugin.conf
+ private Set<PluginAwareness> awareness = ImmutableSet.of();
+ private String apiVersion = null;
+ private List<String> libraries = ImmutableList.of();
++ // Paper start - plugin loader api
++ private String paperPluginLoader;
++ @org.jetbrains.annotations.ApiStatus.Internal @org.jetbrains.annotations.Nullable
++ public String getPaperPluginLoader() {
++ return this.paperPluginLoader;
++ }
++ // Paper end - plugin loader api
+ // Paper start - oh my goddddd
+ /**
+ * Don't use this.
+@@ -1232,6 +1239,23 @@ public final class PluginDescriptionFile implements io.papermc.paper.plugin.conf
+ } else {
+ libraries = ImmutableList.<String>of();
+ }
++ // Paper start - plugin loader api
++ if (map.containsKey("paper-plugin-loader")) {
++ this.paperPluginLoader = map.get("paper-plugin-loader").toString();
++ }
++
++ /*
++ Allow skipping the Bukkit/Spigot 'libraries' list. By default, both the 'libraries'
++ list and the 'paper-plugin-loader' will contribute libraries. It may be desired to only
++ use one or the other. (i.e. 'libraries' on Spigot and 'paper-plugin-loader' on Paper)
++ */
++ if (map.containsKey("paper-skip-libraries")) {
++ String skip = map.get("paper-skip-libraries").toString();
++ if (skip.equalsIgnoreCase("true")) {
++ this.libraries = ImmutableList.of();
++ }
++ }
++ // Paper end - plugin loader api
+
+ try {
+ lazyPermissions = (Map<?, ?>) map.get("permissions");
+diff --git a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java
+index 8e1b6be2462aaa692efa1f72986921a6dc357196..c66252802c51174bc26f266cb5cdecdd856ff220 100644
+--- a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java
++++ b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java
+@@ -84,7 +84,13 @@ public class LibraryLoader
+ @Nullable
+ public ClassLoader createLoader(@NotNull PluginDescriptionFile desc)
+ {
+- if ( desc.getLibraries().isEmpty() )
++ // Paper start - plugin loader api
++ return this.createLoader(desc, null);
++ }
++ @Nullable
++ public ClassLoader createLoader(@NotNull PluginDescriptionFile desc, java.util.@Nullable List<java.nio.file.Path> paperLibraryPaths) {
++ if ( desc.getLibraries().isEmpty() && paperLibraryPaths == null )
++ // Paper end - plugin loader api
+ {
+ return null;
+ }
+@@ -103,17 +109,20 @@ public class LibraryLoader
+ }
+
+ DependencyResult result;
+- try
++ if (!dependencies.isEmpty()) try // Paper - plugin loader api
+ {
+ result = repository.resolveDependencies( session, new DependencyRequest( new CollectRequest( (Dependency) null, dependencies, repositories ), null ) );
+ } catch ( DependencyResolutionException ex )
+ {
+ throw new RuntimeException( "Error resolving libraries", ex );
+- }
++ } else result = null; // Paper - plugin loader api
+
+ List<URL> jarFiles = new ArrayList<>();
+ List<java.nio.file.Path> jarPaths = new ArrayList<>(); // Paper - remap libraries
+- for ( ArtifactResult artifact : result.getArtifactResults() )
++ // Paper start - plugin loader api
++ if (paperLibraryPaths != null) jarPaths.addAll(paperLibraryPaths);
++ if (result != null) for ( ArtifactResult artifact : result.getArtifactResults() )
++ // Paper end - plugin loader api
+ {
+ // Paper start - remap libraries
+ jarPaths.add(artifact.getArtifact().getFile().toPath());
diff --git a/patches/server/0019-Paper-Plugins.patch b/patches/server/0019-Paper-Plugins.patch
index 9b20647620..e5b13df65a 100644
--- a/patches/server/0019-Paper-Plugins.patch
+++ b/patches/server/0019-Paper-Plugins.patch
@@ -877,10 +877,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..5a00e5c41274ded6b837fb81fa8f54616f2b7bc8
+index 0000000000000000000000000000000000000000..18401ede9cd1fc7094c6b74859929938e01795ca
--- /dev/null
+++ b/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/PaperPluginClassLoader.java
-@@ -0,0 +1,205 @@
+@@ -0,0 +1,209 @@
+package io.papermc.paper.plugin.entrypoint.classloader;
+
+import io.papermc.paper.plugin.configuration.PluginMeta;
@@ -936,13 +936,17 @@ index 0000000000000000000000000000000000000000..5a00e5c41274ded6b837fb81fa8f5461
+ this.libraryLoader = libraryLoader;
+
+ this.logger = logger;
-+ if (this.configuration.hasOpenClassloader()) {
++ if (this.configuration().hasOpenClassloader()) {
+ this.group = PaperClassLoaderStorage.instance().registerOpenGroup(this);
+ }
+ }
+
++ private PaperPluginMeta configuration() {
++ return (PaperPluginMeta) this.configuration;
++ }
++
+ public void refreshClassloaderDependencyTree(DependencyContext dependencyContext) {
-+ if (this.configuration.hasOpenClassloader()) {
++ if (this.configuration().hasOpenClassloader()) {
+ return;
+ }
+ if (this.group != null) {
@@ -1088,13 +1092,13 @@ index 0000000000000000000000000000000000000000..5a00e5c41274ded6b837fb81fa8f5461
+}
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
-index 0000000000000000000000000000000000000000..a4c18063854e050bd0c54d488ceeda43c768b6df
+index 0000000000000000000000000000000000000000..967465e542483e93a736129b5f5c6622cefd33fa
--- /dev/null
+++ b/src/main/java/io/papermc/paper/plugin/entrypoint/classloader/PaperSimplePluginClassLoader.java
@@ -0,0 +1,116 @@
+package io.papermc.paper.plugin.entrypoint.classloader;
+
-+import io.papermc.paper.plugin.provider.configuration.PaperPluginMeta;
++import io.papermc.paper.plugin.configuration.PluginMeta;
+import io.papermc.paper.plugin.util.NamespaceChecker;
+import org.jetbrains.annotations.ApiStatus;
+
@@ -1120,13 +1124,13 @@ index 0000000000000000000000000000000000000000..a4c18063854e050bd0c54d488ceeda43
+ ClassLoader.registerAsParallelCapable();
+ }
+
-+ protected final PaperPluginMeta configuration;
++ protected final PluginMeta configuration;
+ protected final Path source;
+ protected final Manifest jarManifest;
+ protected final URL jarUrl;
+ protected final JarFile jar;
+
-+ public PaperSimplePluginClassLoader(Path source, JarFile file, PaperPluginMeta configuration, ClassLoader parentLoader) throws IOException {
++ public PaperSimplePluginClassLoader(Path source, JarFile file, PluginMeta configuration, ClassLoader parentLoader) throws IOException {
+ super(source.getFileName().toString(), new URL[]{source.toUri().toURL()}, parentLoader);
+
+ this.source = source;
diff --git a/patches/server/1047-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch b/patches/server/1047-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch
new file mode 100644
index 0000000000..980c3dc8a0
--- /dev/null
+++ b/patches/server/1047-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch
@@ -0,0 +1,130 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jason Penilla <[email protected]>
+Date: Tue, 21 May 2024 13:18:15 -0700
+Subject: [PATCH] Allow Bukkit plugin to use Paper PluginLoader API
+
+
+diff --git a/src/main/java/io/papermc/paper/plugin/loader/PaperClasspathBuilder.java b/src/main/java/io/papermc/paper/plugin/loader/PaperClasspathBuilder.java
+index f9d4b33050a6fe8c2dabe8e5eec075d95dc513e0..dc106685ecb483c33c06e4f83eda27be58251aad 100644
+--- a/src/main/java/io/papermc/paper/plugin/loader/PaperClasspathBuilder.java
++++ b/src/main/java/io/papermc/paper/plugin/loader/PaperClasspathBuilder.java
+@@ -41,15 +41,7 @@ public class PaperClasspathBuilder implements PluginClasspathBuilder {
+ }
+
+ public PaperPluginClassLoader buildClassLoader(Logger logger, Path source, JarFile jarFile, PaperPluginMeta configuration) {
+- PaperLibraryStore paperLibraryStore = new PaperLibraryStore();
+- for (ClassPathLibrary library : this.libraries) {
+- library.register(paperLibraryStore);
+- }
+-
+- List<Path> paths = paperLibraryStore.getPaths();
+- if (PluginInitializerManager.instance().pluginRemapper != null) {
+- paths = PluginInitializerManager.instance().pluginRemapper.remapLibraries(paths);
+- }
++ List<Path> paths = this.buildLibraryPaths(true);
+ URL[] urls = new URL[paths.size()];
+ for (int i = 0; i < paths.size(); i++) {
+ Path path = paths.get(i);
+@@ -69,4 +61,17 @@ public class PaperClasspathBuilder implements PluginClasspathBuilder {
+ throw new RuntimeException(exception);
+ }
+ }
++
++ public List<Path> buildLibraryPaths(final boolean remap) {
++ PaperLibraryStore paperLibraryStore = new PaperLibraryStore();
++ for (ClassPathLibrary library : this.libraries) {
++ library.register(paperLibraryStore);
++ }
++
++ List<Path> paths = paperLibraryStore.getPaths();
++ if (remap && PluginInitializerManager.instance().pluginRemapper != null) {
++ paths = PluginInitializerManager.instance().pluginRemapper.remapLibraries(paths);
++ }
++ return paths;
++ }
+ }
+diff --git a/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProvider.java b/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProvider.java
+index 75a2b687d58d76b94f8bec111df8613f120ff74b..0fd1040ed376f19c6d5326767baaf3048ce1bfb4 100644
+--- a/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProvider.java
++++ b/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProvider.java
+@@ -40,15 +40,17 @@ public class SpigotPluginProvider implements PluginProvider<JavaPlugin>, Provide
+ private final PluginDescriptionFile description;
+ private final JarFile jarFile;
+ private final Logger logger;
++ private final List<Path> paperLibraryPaths;
+ private final ComponentLogger componentLogger;
+ private ProviderStatus status;
+ private DependencyContext dependencyContext;
+
+- SpigotPluginProvider(Path path, JarFile file, PluginDescriptionFile description) {
++ SpigotPluginProvider(Path path, JarFile file, PluginDescriptionFile description, List<Path> paperLibraryPaths) {
+ this.path = path;
+ this.jarFile = file;
+ this.description = description;
+ this.logger = PaperPluginLogger.getLogger(description);
++ this.paperLibraryPaths = paperLibraryPaths;
+ this.componentLogger = ComponentLogger.logger(this.logger.getName());
+ }
+
+@@ -120,7 +122,7 @@ public class SpigotPluginProvider implements PluginProvider<JavaPlugin>, Provide
+
+ final PluginClassLoader loader;
+ try {
+- loader = new PluginClassLoader(this.getClass().getClassLoader(), this.description, dataFolder, this.path.toFile(), LIBRARY_LOADER.createLoader(this.description), this.jarFile, this.dependencyContext); // Paper
++ loader = new PluginClassLoader(this.getClass().getClassLoader(), this.description, dataFolder, this.path.toFile(), LIBRARY_LOADER.createLoader(this.description, this.paperLibraryPaths), this.jarFile, this.dependencyContext); // Paper
+ } catch (InvalidPluginException ex) {
+ throw ex;
+ } catch (Throwable ex) {
+diff --git a/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProviderFactory.java b/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProviderFactory.java
+index fdb52ad85cfaa1d53aadcad72cec3d3c8c12c058..38075b7348ad7ca3cfece2bfae63e0cce827c694 100644
+--- a/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProviderFactory.java
++++ b/src/main/java/io/papermc/paper/plugin/provider/type/spigot/SpigotPluginProviderFactory.java
+@@ -1,9 +1,18 @@
+ package io.papermc.paper.plugin.provider.type.spigot;
+
++import com.destroystokyo.paper.utils.PaperPluginLogger;
++import io.papermc.paper.plugin.bootstrap.PluginProviderContextImpl;
+ import io.papermc.paper.plugin.entrypoint.classloader.BytecodeModifyingURLClassLoader;
++import io.papermc.paper.plugin.entrypoint.classloader.PaperSimplePluginClassLoader;
++import io.papermc.paper.plugin.loader.PaperClasspathBuilder;
++import io.papermc.paper.plugin.loader.PluginLoader;
+ import io.papermc.paper.plugin.provider.configuration.serializer.constraints.PluginConfigConstraints;
+ import io.papermc.paper.plugin.provider.type.PluginTypeFactory;
++import io.papermc.paper.plugin.provider.util.ProviderUtil;
+ import io.papermc.paper.util.MappingEnvironment;
++import java.util.List;
++import java.util.logging.Logger;
++import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
+ import org.bukkit.plugin.InvalidDescriptionException;
+ import org.bukkit.plugin.PluginDescriptionFile;
+ import org.bukkit.plugin.java.LibraryLoader;
+@@ -36,7 +45,28 @@ class SpigotPluginProviderFactory implements PluginTypeFactory<SpigotPluginProvi
+ throw new InvalidDescriptionException("Restricted name, cannot use 0x20 (space character) in a plugin name.");
+ }
+
+- return new SpigotPluginProvider(source, file, configuration);
++ final List<Path> paperLibraryPaths;
++ if (configuration.getPaperPluginLoader() != null) {
++ final Logger logger = PaperPluginLogger.getLogger(configuration);
++ PaperClasspathBuilder builder = new PaperClasspathBuilder(PluginProviderContextImpl.create(
++ configuration, ComponentLogger.logger(logger.getName()), source
++ ));
++
++ try (
++ PaperSimplePluginClassLoader simplePluginClassLoader = new PaperSimplePluginClassLoader(source, file, configuration, this.getClass().getClassLoader())
++ ) {
++ PluginLoader loader = ProviderUtil.loadClass(configuration.getPaperPluginLoader(), PluginLoader.class, simplePluginClassLoader);
++ loader.classloader(builder);
++ } catch (IOException e) {
++ throw new RuntimeException(e);
++ }
++
++ paperLibraryPaths = builder.buildLibraryPaths(false);
++ } else {
++ paperLibraryPaths = null;
++ }
++
++ return new SpigotPluginProvider(source, file, configuration, paperLibraryPaths);
+ }
+
+ @Override