mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-28 23:38:25 +01:00
New ClassLoader to allow for inter-plugin communication
By: Dinnerbone <dinnerbone@dinnerbone.com>
This commit is contained in:
parent
0e16bbed64
commit
91007ea0be
2 changed files with 55 additions and 1 deletions
|
@ -8,6 +8,8 @@ import java.io.InputStream;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
@ -37,6 +39,7 @@ public final class JavaPluginLoader implements PluginLoader {
|
||||||
private final Pattern[] fileFilters = new Pattern[] {
|
private final Pattern[] fileFilters = new Pattern[] {
|
||||||
Pattern.compile("\\.jar$"),
|
Pattern.compile("\\.jar$"),
|
||||||
};
|
};
|
||||||
|
private final Map<String, Class<?>> classes = new HashMap<String, Class<?>>();
|
||||||
|
|
||||||
public JavaPluginLoader(Server instance) {
|
public JavaPluginLoader(Server instance) {
|
||||||
server = instance;
|
server = instance;
|
||||||
|
@ -67,7 +70,7 @@ public final class JavaPluginLoader implements PluginLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
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<?> jarClass = Class.forName(description.getMain(), true, loader);
|
||||||
Class<? extends JavaPlugin> plugin = jarClass.asSubclass(JavaPlugin.class);
|
Class<? extends JavaPlugin> plugin = jarClass.asSubclass(JavaPlugin.class);
|
||||||
Constructor<? extends JavaPlugin> constructor = plugin.getConstructor(PluginLoader.class, Server.class, PluginDescriptionFile.class, File.class, ClassLoader.class);
|
Constructor<? extends JavaPlugin> 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;
|
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) {
|
public void callEvent(RegisteredListener registration, Event event) {
|
||||||
Listener listener = registration.getListener();
|
Listener listener = registration.getListener();
|
||||||
|
|
||||||
|
|
|
@ -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<String, Class<?>> classes = new HashMap<String, Class<?>>();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue