diff --git a/paper-api/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/paper-api/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java index 1a5b9210f4..5ec11716d7 100644 --- a/paper-api/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java +++ b/paper-api/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java @@ -8,6 +8,8 @@ import java.io.InputStream; import java.lang.reflect.Constructor; import java.net.URL; import java.net.URLClassLoader; +import java.util.HashMap; +import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.regex.Pattern; @@ -37,6 +39,7 @@ public final class JavaPluginLoader implements PluginLoader { private final Pattern[] fileFilters = new Pattern[] { Pattern.compile("\\.jar$"), }; + private final Map> classes = new HashMap>(); public JavaPluginLoader(Server instance) { server = instance; @@ -67,7 +70,7 @@ public final class JavaPluginLoader implements PluginLoader { } try { - ClassLoader loader = URLClassLoader.newInstance(new URL[]{file.toURI().toURL()}, getClass().getClassLoader()); + ClassLoader loader = new PluginClassLoader(this, new URL[]{file.toURI().toURL()}, getClass().getClassLoader()); Class jarClass = Class.forName(description.getMain(), true, loader); Class plugin = jarClass.asSubclass(JavaPlugin.class); Constructor constructor = plugin.getConstructor(PluginLoader.class, Server.class, PluginDescriptionFile.class, File.class, ClassLoader.class); @@ -84,6 +87,14 @@ public final class JavaPluginLoader implements PluginLoader { return fileFilters; } + public Class getClassByName(final String name) { + return classes.get(name); + } + + public void setClass(final String name, final Class clazz) { + classes.put(name, clazz); + } + public void callEvent(RegisteredListener registration, Event event) { Listener listener = registration.getListener(); diff --git a/paper-api/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/paper-api/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java new file mode 100644 index 0000000000..987d5e6895 --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java @@ -0,0 +1,43 @@ + +package org.bukkit.plugin.java; + +import java.net.URL; +import java.net.URLClassLoader; +import java.security.AccessController; +import java.util.HashMap; +import java.util.Map; + +/** + * A ClassLoader for plugins, to allow shared classes across multiple plugins + */ +public class PluginClassLoader extends URLClassLoader { + private final JavaPluginLoader loader; + private final Map> classes = new HashMap>(); + + public PluginClassLoader(final JavaPluginLoader loader, final URL[] urls, final ClassLoader parent) { + super(urls, parent); + + this.loader = loader; + } + + @Override + protected Class findClass(String name) throws ClassNotFoundException { + Class result = classes.get(name); + + if (result == null) { + result = loader.getClassByName(name); + + if (result == null) { + result = super.findClass(name); + + if (result != null) { + loader.setClass(name, result); + } + } + + classes.put(name, result); + } + + return result; + } +}