diff --git a/pf4j/src/main/java/org/pf4j/PluginClassLoader.java b/pf4j/src/main/java/org/pf4j/PluginClassLoader.java index 8d0f2e6..d11e7b9 100644 --- a/pf4j/src/main/java/org/pf4j/PluginClassLoader.java +++ b/pf4j/src/main/java/org/pf4j/PluginClassLoader.java @@ -49,6 +49,7 @@ public class PluginClassLoader extends URLClassLoader { private final PluginManager pluginManager; private final PluginDescriptor pluginDescriptor; private final ClassLoadingStrategy classLoadingStrategy; + private boolean closed; public PluginClassLoader(PluginManager pluginManager, PluginDescriptor pluginDescriptor, ClassLoader parent) { this(pluginManager, pluginDescriptor, parent, ClassLoadingStrategy.PDA); @@ -206,7 +207,6 @@ public class PluginClassLoader extends URLClassLoader { return null; } - @Override public Enumeration getResources(String name) throws IOException { List resources = new ArrayList<>(); @@ -231,6 +231,27 @@ public class PluginClassLoader extends URLClassLoader { return Collections.enumeration(resources); } + /** + * Closes this class loader. + *

+ * This method should be called when the class loader is no longer needed. + */ + @Override + public void close() throws IOException { + super.close(); + + closed = true; + } + + /** + * Returns whether this class loader has been closed. + * + * @return {@code true} if this class loader has been closed, {@code false} otherwise + */ + public boolean isClosed() { + return closed; + } + /** * Loads the class with the specified name from the dependencies of the plugin. * diff --git a/pf4j/src/test/java/org/pf4j/PluginClassLoaderTest.java b/pf4j/src/test/java/org/pf4j/PluginClassLoaderTest.java index fb75f27..e74166e 100644 --- a/pf4j/src/test/java/org/pf4j/PluginClassLoaderTest.java +++ b/pf4j/src/test/java/org/pf4j/PluginClassLoaderTest.java @@ -35,12 +35,16 @@ import java.util.Collections; import java.util.Enumeration; import java.util.List; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * @author Sebastian Lövdahl */ -public class PluginClassLoaderTest { +class PluginClassLoaderTest { private TestPluginManager pluginManager; private TestPluginManager pluginManagerParentFirst; @@ -125,8 +129,8 @@ public class PluginClassLoaderTest { Path jarsDirectoryPath = pluginDependencyZip.unzippedPath().resolve(jarsDirectory); List jars = FileUtils.getJars(jarsDirectoryPath); for (File jar : jars) { - parentLastPluginDependencyClassLoader.addFile(jar); - parentFirstPluginDependencyClassLoader.addFile(jar); + parentLastPluginDependencyClassLoader.addFile(jar); + parentFirstPluginDependencyClassLoader.addFile(jar); } } @@ -321,6 +325,12 @@ public class PluginClassLoaderTest { assertNumberOfResourcesAndFirstLineOfFirstElement(3, "parent", resources); } + @Test + void isClosed() throws IOException { + parentLastPluginClassLoader.close(); + assertTrue(parentLastPluginClassLoader.isClosed()); + } + private static void assertFirstLine(String expected, URL resource) throws URISyntaxException, IOException { assertNotNull(resource); assertEquals(expected, Files.readAllLines(Paths.get(resource.toURI())).get(0)); @@ -334,14 +344,16 @@ public class PluginClassLoaderTest { assertEquals(expectedFirstLine, Files.readAllLines(Paths.get(firstResource.toURI())).get(0)); } - class TestPluginManager extends DefaultPluginManager { + static class TestPluginManager extends DefaultPluginManager { - public TestPluginManager(Path pluginsPath) { - super(pluginsPath); - } + public TestPluginManager(Path pluginsPath) { + super(pluginsPath); + } + + void addClassLoader(String pluginId, PluginClassLoader classLoader) { + getPluginClassLoaders().put(pluginId, classLoader); + } - void addClassLoader(String pluginId, PluginClassLoader classLoader) { - getPluginClassLoaders().put(pluginId, classLoader); - } } + }