Cleanup PluginClassLoader when disabling plugins

This commit is contained in:
Frank van der Heijden 2020-06-09 11:32:03 +02:00
parent 64e18c7d4e
commit 68efbb0635
No known key found for this signature in database
GPG key ID: 26DA56488D314D11
3 changed files with 80 additions and 0 deletions

View file

@ -6,12 +6,15 @@ import org.bukkit.Bukkit;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.plugin.InvalidPluginException; import org.bukkit.plugin.InvalidPluginException;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.PluginClassLoader;
import java.io.File; import java.io.File;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.set;
public class PluginManager { public class PluginManager {
public static LoadResult loadPlugin(String jarFile) { public static LoadResult loadPlugin(String jarFile) {
@ -45,6 +48,7 @@ public class PluginManager {
Bukkit.getPluginManager().disablePlugin(plugin); Bukkit.getPluginManager().disablePlugin(plugin);
RSimplePluginManager.getPlugins(Bukkit.getPluginManager()).remove(plugin); RSimplePluginManager.getPlugins(Bukkit.getPluginManager()).remove(plugin);
RSimplePluginManager.removeLookupName(Bukkit.getPluginManager(), plugin.getName()); RSimplePluginManager.removeLookupName(Bukkit.getPluginManager(), plugin.getName());
clearClassLoader(RJavaPlugin.getClassLoader(plugin));
RCraftingManager.removeRecipesFor(plugin); RCraftingManager.removeRecipesFor(plugin);
} catch (Exception ex) { } catch (Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
@ -54,6 +58,19 @@ public class PluginManager {
return Result.SUCCESS; return Result.SUCCESS;
} }
public static void clearClassLoader(ClassLoader loader) throws IllegalAccessException {
if (loader == null) return;
if (loader instanceof PluginClassLoader) {
clearClassLoader((PluginClassLoader) loader);
}
}
public static void clearClassLoader(PluginClassLoader loader) throws IllegalAccessException {
if (loader == null) return;
set(RPluginClassLoader.getFields(), loader, "plugin", null);
set(RPluginClassLoader.getFields(), loader, "pluginInit", null);
}
public static Result enablePlugin(Plugin plugin) { public static Result enablePlugin(Plugin plugin) {
if (plugin == null) return Result.NOT_EXISTS; if (plugin == null) return Result.NOT_EXISTS;
if (Bukkit.getPluginManager().isPluginEnabled(plugin.getName())) return Result.ALREADY_ENABLED; if (Bukkit.getPluginManager().isPluginEnabled(plugin.getName())) return Result.ALREADY_ENABLED;

View file

@ -0,0 +1,32 @@
package net.frankheijden.serverutils.reflection;
import org.bukkit.plugin.java.JavaPlugin;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.MethodParam.methodOf;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.VersionParam.ALL_VERSIONS;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.getAllMethods;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.invoke;
public class RJavaPlugin {
private static Class<?> javaPluginClass;
private static Map<String, Method> methods;
static {
try {
javaPluginClass = JavaPlugin.class;
methods = getAllMethods(javaPluginClass,
methodOf("getClassLoader", ALL_VERSIONS));
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static ClassLoader getClassLoader(Object instance) throws InvocationTargetException, IllegalAccessException {
return (ClassLoader) invoke(methods, instance, "getClassLoader");
}
}

View file

@ -0,0 +1,31 @@
package net.frankheijden.serverutils.reflection;
import org.bukkit.plugin.java.PluginClassLoader;
import java.lang.reflect.*;
import java.util.Map;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.FieldParam.fieldOf;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.VersionParam.ALL_VERSIONS;
import static net.frankheijden.serverutils.reflection.ReflectionUtils.getAllFields;
public class RPluginClassLoader {
private static Class<?> pluginClassLoaderClass;
private static Map<String, Field> fields;
static {
try {
pluginClassLoaderClass = PluginClassLoader.class;
fields = getAllFields(pluginClassLoaderClass,
fieldOf("plugin", ALL_VERSIONS),
fieldOf("pluginInit", ALL_VERSIONS));
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static Map<String, Field> getFields() {
return fields;
}
}