123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347 |
- /*
- * Copyright (C) 2012-present the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.pf4j;
-
- import org.junit.jupiter.api.AfterEach;
- import org.junit.jupiter.api.BeforeAll;
- import org.junit.jupiter.api.BeforeEach;
- import org.junit.jupiter.api.Test;
- import org.junit.jupiter.api.io.TempDir;
- import org.pf4j.test.PluginZip;
- import org.pf4j.util.FileUtils;
-
- import java.io.File;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.net.URISyntaxException;
- import java.net.URL;
- import java.nio.file.Files;
- import java.nio.file.Path;
- import java.nio.file.Paths;
- import java.util.Collections;
- import java.util.Enumeration;
- import java.util.List;
-
- import static org.junit.jupiter.api.Assertions.*;
-
- /**
- * @author Sebastian Lövdahl
- */
- public class PluginClassLoaderTest {
-
- private TestPluginManager pluginManager;
- private TestPluginManager pluginManagerParentFirst;
- private DefaultPluginDescriptor pluginDependencyDescriptor;
- private DefaultPluginDescriptor pluginDescriptor;
-
- private PluginClassLoader parentLastPluginClassLoader;
- private PluginClassLoader parentFirstPluginClassLoader;
-
- private PluginClassLoader parentLastPluginDependencyClassLoader;
- private PluginClassLoader parentFirstPluginDependencyClassLoader;
-
- @TempDir
- Path pluginsPath;
-
- @BeforeAll
- static void setUpGlobal() throws IOException, URISyntaxException {
- Path parentClassPathBase = Paths.get(PluginClassLoaderTest.class.getClassLoader().getResource(".").toURI());
-
- File metaInfFile = parentClassPathBase.resolve("META-INF").toFile();
- if (metaInfFile.mkdir()) {
- // Only delete the directory if this test created it, guarding for any future usages of the directory.
- metaInfFile.deleteOnExit();
- }
-
- createFile(parentClassPathBase.resolve("META-INF").resolve("file-only-in-parent"));
- createFile(parentClassPathBase.resolve("META-INF").resolve("file-in-both-parent-and-dependency-and-plugin"));
- createFile(parentClassPathBase.resolve("META-INF").resolve("file-in-both-parent-and-dependency"));
- createFile(parentClassPathBase.resolve("META-INF").resolve("file-in-both-parent-and-plugin"));
- }
-
- private static void createFile(Path pathToFile) throws IOException {
- File file = pathToFile.toFile();
-
- file.deleteOnExit();
- assertTrue(file.exists() || file.createNewFile(), "failed to create '" + pathToFile + "'");
- try (PrintWriter printWriter = new PrintWriter(file)) {
- printWriter.write("parent");
- }
- }
-
- @BeforeEach
- void setUp() throws IOException {
- pluginManager = new TestPluginManager(pluginsPath);
- pluginManagerParentFirst = new TestPluginManager(pluginsPath);
-
- pluginDependencyDescriptor = new DefaultPluginDescriptor();
- pluginDependencyDescriptor.setPluginId("myDependency");
- pluginDependencyDescriptor.setPluginVersion("1.2.3");
- pluginDependencyDescriptor.setPluginDescription("My plugin");
- pluginDependencyDescriptor.setDependencies("");
- pluginDependencyDescriptor.setProvider("Me");
- pluginDependencyDescriptor.setRequires("5.0.0");
-
-
- Path pluginDependencyPath = pluginsPath.resolve(pluginDependencyDescriptor.getPluginId() + "-" + pluginDependencyDescriptor.getVersion() + ".zip");
- PluginZip pluginDependencyZip = new PluginZip.Builder(pluginDependencyPath, pluginDependencyDescriptor.getPluginId())
- .pluginVersion(pluginDependencyDescriptor.getVersion())
- .addFile(Paths.get("classes/META-INF/dependency-file"), "dependency")
- .addFile(Paths.get("classes/META-INF/file-in-both-parent-and-dependency-and-plugin"), "dependency")
- .addFile(Paths.get("classes/META-INF/file-in-both-parent-and-dependency"), "dependency")
- .build();
-
- FileUtils.expandIfZip(pluginDependencyZip.path());
-
- PluginClasspath pluginDependencyClasspath = new DefaultPluginClasspath();
-
- parentLastPluginDependencyClassLoader = new PluginClassLoader(pluginManager, pluginDependencyDescriptor, PluginClassLoaderTest.class.getClassLoader());
- parentFirstPluginDependencyClassLoader = new PluginClassLoader(pluginManagerParentFirst, pluginDependencyDescriptor, PluginClassLoaderTest.class.getClassLoader(), true);
-
- pluginManager.addClassLoader(pluginDependencyDescriptor.getPluginId(), parentLastPluginDependencyClassLoader);
- pluginManagerParentFirst.addClassLoader(pluginDependencyDescriptor.getPluginId(), parentFirstPluginDependencyClassLoader);
-
-
- for (String classesDirectory : pluginDependencyClasspath.getClassesDirectories()) {
- File classesDirectoryFile = pluginDependencyZip.unzippedPath().resolve(classesDirectory).toFile();
- parentLastPluginDependencyClassLoader.addFile(classesDirectoryFile);
- parentFirstPluginDependencyClassLoader.addFile(classesDirectoryFile);
- }
-
- for (String jarsDirectory : pluginDependencyClasspath.getJarsDirectories()) {
- Path jarsDirectoryPath = pluginDependencyZip.unzippedPath().resolve(jarsDirectory);
- List<File> jars = FileUtils.getJars(jarsDirectoryPath);
- for (File jar : jars) {
- parentLastPluginDependencyClassLoader.addFile(jar);
- parentFirstPluginDependencyClassLoader.addFile(jar);
- }
- }
-
- pluginDescriptor = new DefaultPluginDescriptor();
- pluginDescriptor.setPluginId("myPlugin");
- pluginDescriptor.setPluginVersion("1.2.3");
- pluginDescriptor.setPluginDescription("My plugin");
- pluginDescriptor.setDependencies("myDependency");
- pluginDescriptor.setProvider("Me");
- pluginDescriptor.setRequires("5.0.0");
-
- Path pluginPath = pluginsPath.resolve(pluginDescriptor.getPluginId() + "-" + pluginDescriptor.getVersion() + ".zip");
- PluginZip pluginZip = new PluginZip.Builder(pluginPath, pluginDescriptor.getPluginId())
- .pluginVersion(pluginDescriptor.getVersion())
- .addFile(Paths.get("classes/META-INF/plugin-file"), "plugin")
- .addFile(Paths.get("classes/META-INF/file-in-both-parent-and-dependency-and-plugin"), "plugin")
- .addFile(Paths.get("classes/META-INF/file-in-both-parent-and-plugin"), "plugin")
- .build();
-
- FileUtils.expandIfZip(pluginZip.path());
-
- PluginClasspath pluginClasspath = new DefaultPluginClasspath();
-
- parentLastPluginClassLoader = new PluginClassLoader(pluginManager, pluginDescriptor, PluginClassLoaderTest.class.getClassLoader());
- parentFirstPluginClassLoader = new PluginClassLoader(pluginManager, pluginDescriptor, PluginClassLoaderTest.class.getClassLoader(), true);
-
- pluginManager.addClassLoader(pluginDescriptor.getPluginId(), parentLastPluginClassLoader);
- pluginManagerParentFirst.addClassLoader(pluginDescriptor.getPluginId(), parentFirstPluginClassLoader);
-
- for (String classesDirectory : pluginClasspath.getClassesDirectories()) {
- File classesDirectoryFile = pluginZip.unzippedPath().resolve(classesDirectory).toFile();
- parentLastPluginClassLoader.addFile(classesDirectoryFile);
- parentFirstPluginClassLoader.addFile(classesDirectoryFile);
- }
-
- for (String jarsDirectory : pluginClasspath.getJarsDirectories()) {
- Path jarsDirectoryPath = pluginZip.unzippedPath().resolve(jarsDirectory);
- List<File> jars = FileUtils.getJars(jarsDirectoryPath);
- for (File jar : jars) {
- parentLastPluginClassLoader.addFile(jar);
- parentFirstPluginClassLoader.addFile(jar);
- }
- }
- }
-
- @AfterEach
- void tearDown() {
- pluginManager = null;
- pluginDependencyDescriptor = null;
- pluginDescriptor = null;
- parentLastPluginClassLoader = null;
- parentFirstPluginClassLoader = null;
- }
-
- @Test
- void parentLastGetResourceNonExisting() {
- assertNull(parentLastPluginClassLoader.getResource("META-INF/non-existing-file"));
- }
-
- @Test
- void parentFirstGetResourceNonExisting() {
- assertNull(parentFirstPluginClassLoader.getResource("META-INF/non-existing-file"));
- }
-
- @Test
- void parentLastGetResourceExistsInParent() throws IOException, URISyntaxException {
- URL resource = parentLastPluginClassLoader.getResource("META-INF/file-only-in-parent");
- assertFirstLine("parent", resource);
- }
-
- @Test
- void parentFirstGetResourceExistsInParent() throws IOException, URISyntaxException {
- URL resource = parentFirstPluginClassLoader.getResource("META-INF/file-only-in-parent");
- assertFirstLine("parent", resource);
- }
-
- @Test
- void parentLastGetResourceExistsOnlyInPlugin() throws IOException, URISyntaxException {
- URL resource = parentLastPluginClassLoader.getResource("META-INF/plugin-file");
- assertFirstLine("plugin", resource);
- }
-
- @Test
- void parentFirstGetResourceExistsOnlyInPlugin() throws IOException, URISyntaxException {
- URL resource = parentFirstPluginClassLoader.getResource("META-INF/plugin-file");
- assertFirstLine("plugin", resource);
- }
-
- @Test
- void parentLastGetResourceExistsOnlyInDependnecy() throws IOException, URISyntaxException {
- URL resource = parentLastPluginClassLoader.getResource("META-INF/dependency-file");
- assertFirstLine("dependency", resource);
- }
-
- @Test
- void parentFirstGetResourceExistsOnlyInDependency() throws IOException, URISyntaxException {
- URL resource = parentFirstPluginClassLoader.getResource("META-INF/dependency-file");
- assertFirstLine("dependency", resource);
- }
-
- @Test
- void parentLastGetResourceExistsInBothParentAndPlugin() throws URISyntaxException, IOException {
- URL resource = parentLastPluginClassLoader.getResource("META-INF/file-in-both-parent-and-plugin");
- assertFirstLine("plugin", resource);
- }
-
- @Test
- void parentFirstGetResourceExistsInBothParentAndPlugin() throws URISyntaxException, IOException {
- URL resource = parentFirstPluginClassLoader.getResource("META-INF/file-in-both-parent-and-plugin");
- assertFirstLine("parent", resource);
- }
-
- @Test
- void parentLastGetResourceExistsInParentAndDependencyAndPlugin() throws URISyntaxException, IOException {
- URL resource = parentLastPluginClassLoader.getResource("META-INF/file-in-both-parent-and-dependency-and-plugin");
- assertFirstLine("plugin", resource);
- }
-
- @Test
- void parentFirstGetResourceExistsInParentAndDependencyAndPlugin() throws URISyntaxException, IOException {
- URL resource = parentFirstPluginClassLoader.getResource("META-INF/file-in-both-parent-and-dependency-and-plugin");
- assertFirstLine("parent", resource);
- }
-
- @Test
- void parentLastGetResourcesNonExisting() throws IOException {
- assertFalse(parentLastPluginClassLoader.getResources("META-INF/non-existing-file").hasMoreElements());
- }
-
- @Test
- void parentFirstGetResourcesNonExisting() throws IOException {
- assertFalse(parentFirstPluginClassLoader.getResources("META-INF/non-existing-file").hasMoreElements());
- }
-
- @Test
- void parentLastGetResourcesExistsInParent() throws IOException, URISyntaxException {
- Enumeration<URL> resources = parentLastPluginClassLoader.getResources("META-INF/file-only-in-parent");
- assertNumberOfResourcesAndFirstLineOfFirstElement(1, "parent", resources);
- }
-
- @Test
- void parentFirstGetResourcesExistsInParent() throws IOException, URISyntaxException {
- Enumeration<URL> resources = parentFirstPluginClassLoader.getResources("META-INF/file-only-in-parent");
- assertNumberOfResourcesAndFirstLineOfFirstElement(1, "parent", resources);
- }
-
- @Test
- void parentLastGetResourcesExistsOnlyInDependency() throws IOException, URISyntaxException {
- Enumeration<URL> resources = parentLastPluginClassLoader.getResources("META-INF/dependency-file");
- assertNumberOfResourcesAndFirstLineOfFirstElement(1, "dependency", resources);
- }
-
- @Test
- void parentFirstGetResourcesExistsOnlyInDependency() throws IOException, URISyntaxException {
- Enumeration<URL> resources = parentFirstPluginClassLoader.getResources("META-INF/dependency-file");
- assertNumberOfResourcesAndFirstLineOfFirstElement(1, "dependency", resources);
- }
-
- @Test
- void parentLastGetResourcesExistsOnlyInPlugin() throws IOException, URISyntaxException {
- Enumeration<URL> resources = parentLastPluginClassLoader.getResources("META-INF/plugin-file");
- assertNumberOfResourcesAndFirstLineOfFirstElement(1, "plugin", resources);
- }
-
- @Test
- void parentFirstGetResourcesExistsOnlyInPlugin() throws IOException, URISyntaxException {
- Enumeration<URL> resources = parentFirstPluginClassLoader.getResources("META-INF/plugin-file");
- assertNumberOfResourcesAndFirstLineOfFirstElement(1, "plugin", resources);
- }
-
- @Test
- void parentLastGetResourcesExistsInBothParentAndPlugin() throws URISyntaxException, IOException {
- Enumeration<URL> resources = parentLastPluginClassLoader.getResources("META-INF/file-in-both-parent-and-plugin");
- assertNumberOfResourcesAndFirstLineOfFirstElement(2, "plugin", resources);
- }
-
- @Test
- void parentFirstGetResourcesExistsInBothParentAndPlugin() throws URISyntaxException, IOException {
- Enumeration<URL> resources = parentFirstPluginClassLoader.getResources("META-INF/file-in-both-parent-and-plugin");
- assertNumberOfResourcesAndFirstLineOfFirstElement(2, "parent", resources);
- }
-
- @Test
- void parentLastGetResourcesExistsInParentAndDependencyAndPlugin() throws URISyntaxException, IOException {
- Enumeration<URL> resources = parentLastPluginClassLoader.getResources("META-INF/file-in-both-parent-and-dependency-and-plugin");
- assertNumberOfResourcesAndFirstLineOfFirstElement(3, "plugin", resources);
- }
-
- @Test
- void parentFirstGetResourcesExistsInParentAndDependencyAndPlugin() throws URISyntaxException, IOException {
- Enumeration<URL> resources = parentFirstPluginClassLoader.getResources("META-INF/file-in-both-parent-and-dependency-and-plugin");
- assertNumberOfResourcesAndFirstLineOfFirstElement(3, "parent", resources);
- }
-
- private static void assertFirstLine(String expected, URL resource) throws URISyntaxException, IOException {
- assertNotNull(resource);
- assertEquals(expected, Files.readAllLines(Paths.get(resource.toURI())).get(0));
- }
-
- private static void assertNumberOfResourcesAndFirstLineOfFirstElement(int expectedCount, String expectedFirstLine, Enumeration<URL> resources) throws URISyntaxException, IOException {
- List<URL> list = Collections.list(resources);
- assertEquals(expectedCount, list.size());
-
- URL firstResource = list.get(0);
- assertEquals(expectedFirstLine, Files.readAllLines(Paths.get(firstResource.toURI())).get(0));
- }
-
- class TestPluginManager extends DefaultPluginManager {
-
- public TestPluginManager(Path pluginsPath) {
- super(pluginsPath);
- }
-
- void addClassLoader(String pluginId, PluginClassLoader classLoader) {
- getPluginClassLoaders().put(pluginId, classLoader);
- }
- }
- }
|