Set libraryLoader to null & clear classes in PluginClassLoader (bukkit)

This commit is contained in:
Frank van der Heijden 2021-08-04 20:17:03 +02:00
parent 870e2bcae5
commit fd69f74b22
No known key found for this signature in database
GPG key ID: B808721C2DD5B5B8
5 changed files with 23 additions and 18 deletions

View file

@ -146,12 +146,11 @@ public class BukkitPluginManager extends AbstractPluginManager<Plugin, BukkitPlu
RSimplePluginManager.removeLookupName(Bukkit.getPluginManager(), pluginId);
ClassLoader classLoader = plugin.getClass().getClassLoader();
RPluginClassLoader.clearClassLoader(classLoader);
PluginLoader loader = RPluginClassLoader.getLoader(classLoader);
Map<String, Class<?>> classes = RPluginClassLoader.getClasses(classLoader);
RJavaPluginLoader.removeClasses(loader, classes.keySet());
RPluginClassLoader.clearClassLoader(classLoader);
RJavaPlugin.clearJavaPlugin(plugin);
addIfInstance(closeables, RPluginClassLoader.getLibraryLoader(classLoader));

View file

@ -1,7 +1,6 @@
package net.frankheijden.serverutils.bukkit.reflection;
import dev.frankheijden.minecraftreflection.MinecraftReflection;
import java.io.Closeable;
import java.io.File;
import org.bukkit.plugin.java.JavaPlugin;
@ -23,12 +22,9 @@ public class RJavaPlugin {
/**
* Clears the JavaPlugin from instances and returns the classloader associated with it.
* @param instance The instance of the JavaPlugin.
* @return The classloader associated with it.
*/
public static Closeable clearJavaPlugin(Object instance) {
public static void clearJavaPlugin(Object instance) {
reflection.set(instance, "loader", null);
reflection.set(instance, "classLoader", null);
return null;
}
}

View file

@ -1,8 +1,11 @@
package net.frankheijden.serverutils.bukkit.reflection;
import java.lang.reflect.Field;
import java.util.Map;
import dev.frankheijden.minecraftreflection.MinecraftReflection;
import dev.frankheijden.minecraftreflection.MinecraftReflectionVersion;
import java.util.Map;
import dev.frankheijden.minecraftreflection.Reflection;
import net.frankheijden.serverutils.common.utils.ReflectionUtils;
import org.bukkit.plugin.PluginLoader;
public class RPluginClassLoader {
@ -31,22 +34,29 @@ public class RPluginClassLoader {
}
public static ClassLoader getLibraryLoader(ClassLoader loader) {
if (loader == null && MinecraftReflectionVersion.MINOR <= 16) return null;
if (loader == null || MinecraftReflectionVersion.MINOR <= 16) return null;
return reflection.get(loader, "libraryLoader");
}
/**
* Clears the plugin fields from the specified PluginClassLoader.
* @param pluginLoader The plugin loader instance.
*/
public static void clearPluginClassLoader(Object pluginLoader) {
if (pluginLoader == null) return;
public static void clearPluginClassLoader(Object classLoader) {
if (classLoader == null) return;
reflection.set(pluginLoader, "plugin", null);
reflection.set(pluginLoader, "pluginInit", null);
reflection.set(classLoader, "loader", null);
if (MinecraftReflectionVersion.MINOR > 16) {
ReflectionUtils.doPrivilegedWithUnsafe(unsafe -> {
Field libraryLoaderField = Reflection.getField(reflection.getClazz(), "libraryLoader");
unsafe.putObject(classLoader, unsafe.objectFieldOffset(libraryLoaderField), null);
});
}
reflection.set(classLoader, "plugin", null);
reflection.set(classLoader, "pluginInit", null);
getClasses(classLoader).clear();
}
public static Map<String, Class<?>> getClasses(Object pluginLoader) {
return reflection.get(pluginLoader, "classes");
public static Map<String, Class<?>> getClasses(Object classLoader) {
return reflection.get(classLoader, "classes");
}
}