diff --git a/src/main/java/net/frankheijden/serverutils/managers/PluginManager.java b/src/main/java/net/frankheijden/serverutils/managers/PluginManager.java index d5ca3f2..1517987 100644 --- a/src/main/java/net/frankheijden/serverutils/managers/PluginManager.java +++ b/src/main/java/net/frankheijden/serverutils/managers/PluginManager.java @@ -6,12 +6,15 @@ import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.plugin.InvalidPluginException; import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.PluginClassLoader; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.Map; +import static net.frankheijden.serverutils.reflection.ReflectionUtils.set; + public class PluginManager { public static LoadResult loadPlugin(String jarFile) { @@ -45,6 +48,7 @@ public class PluginManager { Bukkit.getPluginManager().disablePlugin(plugin); RSimplePluginManager.getPlugins(Bukkit.getPluginManager()).remove(plugin); RSimplePluginManager.removeLookupName(Bukkit.getPluginManager(), plugin.getName()); + clearClassLoader(RJavaPlugin.getClassLoader(plugin)); RCraftingManager.removeRecipesFor(plugin); } catch (Exception ex) { ex.printStackTrace(); @@ -54,6 +58,19 @@ public class PluginManager { 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) { if (plugin == null) return Result.NOT_EXISTS; if (Bukkit.getPluginManager().isPluginEnabled(plugin.getName())) return Result.ALREADY_ENABLED; diff --git a/src/main/java/net/frankheijden/serverutils/reflection/RJavaPlugin.java b/src/main/java/net/frankheijden/serverutils/reflection/RJavaPlugin.java new file mode 100644 index 0000000..4a1ca9b --- /dev/null +++ b/src/main/java/net/frankheijden/serverutils/reflection/RJavaPlugin.java @@ -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 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"); + } +} diff --git a/src/main/java/net/frankheijden/serverutils/reflection/RPluginClassLoader.java b/src/main/java/net/frankheijden/serverutils/reflection/RPluginClassLoader.java new file mode 100644 index 0000000..0e391e0 --- /dev/null +++ b/src/main/java/net/frankheijden/serverutils/reflection/RPluginClassLoader.java @@ -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 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 getFields() { + return fields; + } +}