diff --git a/Spigot-API-Patches/Close-Plugin-Class-Loaders-on-Disable.patch b/Spigot-API-Patches/Close-Plugin-Class-Loaders-on-Disable.patch index 7b48b5eebf..ac9d0d6c6c 100644 --- a/Spigot-API-Patches/Close-Plugin-Class-Loaders-on-Disable.patch +++ b/Spigot-API-Patches/Close-Plugin-Class-Loaders-on-Disable.patch @@ -6,17 +6,276 @@ Subject: [PATCH] Close Plugin Class Loaders on Disable This should close more memory leaks from /reload and disabling plugins, by closing the class loader and the jar file. +diff --git a/src/main/java/org/bukkit/plugin/PluginLoader.java b/src/main/java/org/bukkit/plugin/PluginLoader.java +index e7981a1d..541f85bc 100644 +--- a/src/main/java/org/bukkit/plugin/PluginLoader.java ++++ b/src/main/java/org/bukkit/plugin/PluginLoader.java +@@ -0,0 +0,0 @@ public interface PluginLoader { + * @param plugin Plugin to disable + */ + public void disablePlugin(Plugin plugin); ++ ++ // Paper start - close Classloader on disable ++ /** ++ * Disables the specified plugin ++ *
++ * Attempting to disable a plugin that is not enabled will have no effect ++ * ++ * @param plugin Plugin to disable ++ * @param closeClassloader if the classloader for the Plugin should be closed ++ */ ++ public void disablePlugin(Plugin plugin, boolean closeClassloader); ++ // Paper end - close Classloader on disable + } +diff --git a/src/main/java/org/bukkit/plugin/PluginManager.java b/src/main/java/org/bukkit/plugin/PluginManager.java +index e5638d56..b72d5a9b 100644 +--- a/src/main/java/org/bukkit/plugin/PluginManager.java ++++ b/src/main/java/org/bukkit/plugin/PluginManager.java +@@ -0,0 +0,0 @@ public interface PluginManager { + */ + public void disablePlugin(Plugin plugin); + ++ // Paper start - close Classloader on disable ++ /** ++ * Disables the specified plugin ++ *
++ * Attempting to disable a plugin that is not enabled will have no effect
++ *
++ * @param plugin Plugin to disable
++ * @param closeClassloader if the classloader for the Plugin should be closed
++ */
++ public void disablePlugin(Plugin plugin, boolean closeClassloader);
++ // Paper end - close Classloader on disable
++
+ /**
+ * Gets a {@link Permission} from its fully qualified name
+ *
+diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
+index bd0588a2..cb2b0b9c 100644
+--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
++++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
+@@ -0,0 +0,0 @@ public final class SimplePluginManager implements PluginManager {
+ }
+ }
+
++ // Paper start - close Classloader on disable
+ public void disablePlugins() {
++ disablePlugins(false);
++ }
++
++ public void disablePlugins(boolean closeClassloaders) {
++ // Paper end - close Classloader on disable
+ Plugin[] plugins = getPlugins();
+ for (int i = plugins.length - 1; i >= 0; i--) {
+- disablePlugin(plugins[i]);
++ disablePlugin(plugins[i], closeClassloaders); // Paper - close Classloader on disable
+ }
+ }
+
+- public void disablePlugin(final Plugin plugin) {
++ // Paper start - close Classloader on disable
++ public void disablePlugin(Plugin plugin) {
++ disablePlugin(plugin, false);
++ }
++
++ public void disablePlugin(final Plugin plugin, boolean closeClassloader) {
++ // Paper end - close Classloader on disable
+ if (plugin.isEnabled()) {
+ try {
+- plugin.getPluginLoader().disablePlugin(plugin);
++ plugin.getPluginLoader().disablePlugin(plugin, closeClassloader); // Paper - close Classloader on disable
+ } catch (Throwable ex) {
+ handlePluginException("Error occurred (in the plugin loader) while disabling "
+ + plugin.getDescription().getFullName() + " (Is it up to date?)", ex, plugin); // Paper
+@@ -0,0 +0,0 @@ public final class SimplePluginManager implements PluginManager {
+
+ public void clearPlugins() {
+ synchronized (this) {
+- disablePlugins();
++ disablePlugins(true); // Paper - close Classloader on disable
+ plugins.clear();
+ lookupNames.clear();
+ HandlerList.unregisterAll();
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
-index 40fd71dc..1ea695d5 100644
+index 40fd71dc..d2c538b2 100644
--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
+@@ -0,0 +0,0 @@
+ package org.bukkit.plugin.java;
+
+-import java.io.File;
+-import java.io.FileNotFoundException;
+-import java.io.IOException;
+-import java.io.InputStream;
+-import java.lang.reflect.InvocationTargetException;
+-import java.lang.reflect.Method;
+-import java.util.Arrays;
+-import java.util.HashMap;
+-import java.util.HashSet;
+-import java.util.List;
+-import java.util.Map;
+-import java.util.Set;
+-import java.util.concurrent.CopyOnWriteArrayList;
+-import java.util.jar.JarEntry;
+-import java.util.jar.JarFile;
+-import java.util.logging.Level;
+-import java.util.regex.Pattern;
+-
+ import org.apache.commons.lang.Validate;
+ import org.bukkit.Server;
+ import org.bukkit.Warning;
+@@ -0,0 +0,0 @@ import org.bukkit.Warning.WarningState;
+ import org.bukkit.configuration.serialization.ConfigurationSerializable;
+ import org.bukkit.configuration.serialization.ConfigurationSerialization;
+ import org.bukkit.event.Event;
+-import org.bukkit.event.EventException;
+ import org.bukkit.event.EventHandler;
+ import org.bukkit.event.Listener;
+ import org.bukkit.event.server.PluginDisableEvent;
+@@ -0,0 +0,0 @@ import org.bukkit.plugin.TimedRegisteredListener;
+ import org.bukkit.plugin.UnknownDependencyException;
+ import org.yaml.snakeyaml.error.YAMLException;
+
++import java.io.File;
++import java.io.FileNotFoundException;
++import java.io.IOException;
++import java.io.InputStream;
++import java.lang.reflect.Method;
++import java.util.Arrays;
++import java.util.HashMap;
++import java.util.HashSet;
++import java.util.List;
++import java.util.Map;
++import java.util.Set;
++import java.util.concurrent.CopyOnWriteArrayList;
++import java.util.jar.JarEntry;
++import java.util.jar.JarFile;
++import java.util.logging.Level;
++import java.util.regex.Pattern;
++
+ /**
+ * Represents a Java plugin loader, allowing plugins in the form of .jar
+ */
+ public final class JavaPluginLoader implements PluginLoader {
+ final Server server;
+- private final Pattern[] fileFilters = new Pattern[] { Pattern.compile("\\.jar$"), };
++ private final Pattern[] fileFilters = new Pattern[]{Pattern.compile("\\.jar$"),};
+ private final Map