From 1fb62d26161c44155ea0074e8dfaac9c108875fb Mon Sep 17 00:00:00 2001 From: Emily Date: Sun, 19 Mar 2023 18:35:09 -0300 Subject: [PATCH] Cleanup classloaders on shutdown (#3605) --- .../dependencies/DependencyManager.java | 23 ++++++++++++++++++- .../relocation/RelocationHandler.java | 13 ++++++++++- .../plugin/AbstractLuckPermsPlugin.java | 3 +++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/me/lucko/luckperms/common/dependencies/DependencyManager.java b/common/src/main/java/me/lucko/luckperms/common/dependencies/DependencyManager.java index 710658ef8..71a54a3f0 100644 --- a/common/src/main/java/me/lucko/luckperms/common/dependencies/DependencyManager.java +++ b/common/src/main/java/me/lucko/luckperms/common/dependencies/DependencyManager.java @@ -57,7 +57,7 @@ import java.util.concurrent.Executor; /** * Loads and manages runtime dependencies for the plugin. */ -public class DependencyManager { +public class DependencyManager implements AutoCloseable { /** A registry containing plugin specific behaviour for dependencies. */ private final DependencyRegistry registry; @@ -235,4 +235,25 @@ public class DependencyManager { return cacheDirectory; } + @Override + public void close() { + IOException firstEx = null; + + for (IsolatedClassLoader loader : this.loaders.values()) { + try { + loader.close(); + } catch (IOException ex) { + if (firstEx == null) { + firstEx = ex; + } else { + firstEx.addSuppressed(ex); + } + } + } + + if (firstEx != null) { + firstEx.printStackTrace(); + } + } + } diff --git a/common/src/main/java/me/lucko/luckperms/common/dependencies/relocation/RelocationHandler.java b/common/src/main/java/me/lucko/luckperms/common/dependencies/relocation/RelocationHandler.java index 7ac1fb58b..6d0bb2a37 100644 --- a/common/src/main/java/me/lucko/luckperms/common/dependencies/relocation/RelocationHandler.java +++ b/common/src/main/java/me/lucko/luckperms/common/dependencies/relocation/RelocationHandler.java @@ -30,6 +30,7 @@ import me.lucko.luckperms.common.dependencies.DependencyManager; import me.lucko.luckperms.common.dependencies.classloader.IsolatedClassLoader; import java.io.File; +import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.nio.file.Path; @@ -51,11 +52,12 @@ public class RelocationHandler { private final Method jarRelocatorRunMethod; public RelocationHandler(DependencyManager dependencyManager) { + IsolatedClassLoader classLoader = null; try { // download the required dependencies for remapping dependencyManager.loadDependencies(DEPENDENCIES); // get a classloader containing the required dependencies as sources - IsolatedClassLoader classLoader = dependencyManager.obtainClassLoaderWith(DEPENDENCIES); + classLoader = dependencyManager.obtainClassLoaderWith(DEPENDENCIES); // load the relocator class Class jarRelocatorClass = classLoader.loadClass(JAR_RELOCATOR_CLASS); @@ -67,6 +69,14 @@ public class RelocationHandler { this.jarRelocatorRunMethod = jarRelocatorClass.getDeclaredMethod(JAR_RELOCATOR_RUN_METHOD); this.jarRelocatorRunMethod.setAccessible(true); } catch (Exception e) { + try { + if (classLoader != null) { + classLoader.close(); + } + } catch (IOException ex) { + e.addSuppressed(ex); + } + throw new RuntimeException(e); } } @@ -81,4 +91,5 @@ public class RelocationHandler { Object relocator = this.jarRelocatorConstructor.newInstance(input.toFile(), output.toFile(), mappings); this.jarRelocatorRunMethod.invoke(relocator); } + } diff --git a/common/src/main/java/me/lucko/luckperms/common/plugin/AbstractLuckPermsPlugin.java b/common/src/main/java/me/lucko/luckperms/common/plugin/AbstractLuckPermsPlugin.java index a84ac5007..c06cc04e7 100644 --- a/common/src/main/java/me/lucko/luckperms/common/plugin/AbstractLuckPermsPlugin.java +++ b/common/src/main/java/me/lucko/luckperms/common/plugin/AbstractLuckPermsPlugin.java @@ -292,6 +292,9 @@ public abstract class AbstractLuckPermsPlugin implements LuckPermsPlugin { this.httpClient.dispatcher().executorService().shutdown(); this.httpClient.connectionPool().evictAll(); + // close isolated loaders for non-relocated dependencies + getDependencyManager().close(); + // close classpath appender getBootstrap().getClassPathAppender().close();