You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ma...@apache.org on 2022/06/05 00:06:06 UTC

[logging-log4j2] 07/08: Migrate URLStreamHandlerFactory tests to JUnit 5

This is an automated email from the ASF dual-hosted git repository.

mattsicker pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit 39316b97a272b9612957fefe8e0a97f5e59171ca
Author: Matt Sicker <ma...@apache.org>
AuthorDate: Sat Jun 4 19:03:56 2022 -0500

    Migrate URLStreamHandlerFactory tests to JUnit 5
    
    - Adds URLStreamHandlerFactoryExtension and related annotation
    
    Signed-off-by: Matt Sicker <ma...@apache.org>
---
 .../test/junit/URLStreamHandlerFactories.java      | 58 +++++++++++++
 .../junit/URLStreamHandlerFactoryExtension.java    | 41 +++++++++
 .../test/junit/URLStreamHandlerFactoryRule.java    | 78 -----------------
 .../test/junit/UsingURLStreamHandlerFactory.java   | 42 ++++++++++
 .../util/ResolverUtilCustomProtocolTest.java       | 45 +++++-----
 .../log4j/plugins/util/ResolverUtilTest.java       | 98 +++++++++++-----------
 6 files changed, 213 insertions(+), 149 deletions(-)

diff --git a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/URLStreamHandlerFactories.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/URLStreamHandlerFactories.java
new file mode 100644
index 0000000000..aa11328f70
--- /dev/null
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/URLStreamHandlerFactories.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.logging.log4j.test.junit;
+
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.opentest4j.TestAbortedException;
+
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.net.URLStreamHandlerFactory;
+import java.util.Hashtable;
+import java.util.stream.Stream;
+
+public class URLStreamHandlerFactories {
+    private static final Field FACTORY_FIELD = Stream.of(URL.class.getDeclaredFields())
+            .filter(field -> URLStreamHandlerFactory.class.equals(field.getType()))
+            .findFirst()
+            .orElseThrow(() -> new TestAbortedException("java.net.URL does not declare a java.net.URLStreamHandlerFactory field"));
+    private static final Field HANDLERS_FIELD = FieldUtils.getDeclaredField(URL.class, "handlers", true);
+
+    public static URLStreamHandlerFactory getURLStreamHandlerFactory() {
+        try {
+            return (URLStreamHandlerFactory) FieldUtils.readStaticField(FACTORY_FIELD, true);
+        } catch (IllegalAccessException e) {
+            throw new IllegalAccessError(e.getMessage());
+        }
+    }
+
+    public static void setURLStreamHandlerFactory(final URLStreamHandlerFactory factory) {
+        try {
+            final Object handlers = HANDLERS_FIELD.get(null);
+            if (handlers instanceof Hashtable<?, ?>) {
+                ((Hashtable<?, ?>) handlers).clear();
+            }
+            FieldUtils.writeStaticField(FACTORY_FIELD, null, true);
+        } catch (IllegalAccessException e) {
+            throw new IllegalAccessError(e.getMessage());
+        }
+        if (factory != null) {
+            URL.setURLStreamHandlerFactory(factory);
+        }
+    }
+}
diff --git a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/URLStreamHandlerFactoryExtension.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/URLStreamHandlerFactoryExtension.java
new file mode 100644
index 0000000000..2450657628
--- /dev/null
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/URLStreamHandlerFactoryExtension.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.logging.log4j.test.junit;
+
+import org.apache.logging.log4j.util.ReflectionUtil;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.platform.commons.support.AnnotationSupport;
+
+import java.net.URLStreamHandlerFactory;
+
+public class URLStreamHandlerFactoryExtension implements BeforeAllCallback {
+    @Override
+    public void beforeAll(final ExtensionContext context) throws Exception {
+        final Class<?> testClass = context.getRequiredTestClass();
+        final URLStreamHandlerFactory factory = AnnotationSupport.findAnnotation(testClass, UsingURLStreamHandlerFactory.class)
+                .map(UsingURLStreamHandlerFactory::value)
+                .map(ReflectionUtil::instantiate)
+                .orElseThrow();
+        final URLStreamHandlerFactory oldFactory = URLStreamHandlerFactories.getURLStreamHandlerFactory();
+        URLStreamHandlerFactories.setURLStreamHandlerFactory(factory);
+        context.getStore(ExtensionContext.Namespace.create(getClass(), testClass))
+                .put(URLStreamHandlerFactory.class, (ExtensionContext.Store.CloseableResource) () ->
+                        URLStreamHandlerFactories.setURLStreamHandlerFactory(oldFactory));
+    }
+}
diff --git a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/URLStreamHandlerFactoryRule.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/URLStreamHandlerFactoryRule.java
deleted file mode 100644
index e095260337..0000000000
--- a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/URLStreamHandlerFactoryRule.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.apache.logging.log4j.test.junit;
-
-import org.apache.commons.lang3.reflect.FieldUtils;
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-import org.opentest4j.TestAbortedException;
-
-import java.lang.reflect.Field;
-import java.net.URL;
-import java.net.URLStreamHandlerFactory;
-import java.util.Hashtable;
-import java.util.stream.Stream;
-
-/**
- * Installs and restores the URL URLStreamHandlerFactory before and after tests.
- * <p>
- * Might need tweaking for different JREs.
- * </p>
- */
-public class URLStreamHandlerFactoryRule implements TestRule {
-
-    public URLStreamHandlerFactoryRule() {
-        this(null);
-    }
-
-    public URLStreamHandlerFactoryRule(final URLStreamHandlerFactory newURLStreamHandlerFactory) {
-        this.newURLStreamHandlerFactory = newURLStreamHandlerFactory;
-    }
-
-    private final URLStreamHandlerFactory newURLStreamHandlerFactory;
-
-    void clearURLHandlers() throws Exception {
-        final Object handlers = FieldUtils.readDeclaredStaticField(URL.class, "handlers", true);
-        if (handlers instanceof Hashtable<?, ?>) {
-            ((Hashtable<?, ?>) handlers).clear();
-        }
-    }
-
-    @Override
-    public Statement apply(final Statement base, final Description description) {
-        return new Statement() {
-            @Override
-            public void evaluate() throws Throwable {
-                final Field factoryField = Stream.of(URL.class.getDeclaredFields())
-                        .filter(field -> URLStreamHandlerFactory.class.equals(field.getType()))
-                        .findFirst()
-                        .orElseThrow(() -> new TestAbortedException("java.net URL does not declare a java.net.URLStreamHandlerFactory field"));
-                URLStreamHandlerFactory oldFactory = (URLStreamHandlerFactory) FieldUtils.readStaticField(factoryField, true);
-                URL.setURLStreamHandlerFactory(newURLStreamHandlerFactory);
-                try {
-                    base.evaluate();
-                } finally {
-                    clearURLHandlers();
-                    FieldUtils.writeStaticField(factoryField, null);
-                    URL.setURLStreamHandlerFactory(oldFactory);
-                }
-            }
-        };
-    }
-}
diff --git a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/UsingURLStreamHandlerFactory.java b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/UsingURLStreamHandlerFactory.java
new file mode 100644
index 0000000000..25137a7758
--- /dev/null
+++ b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/UsingURLStreamHandlerFactory.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.logging.log4j.test.junit;
+
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.parallel.Isolated;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.net.URLStreamHandlerFactory;
+
+/**
+ * Test extension to use a custom {@link URLStreamHandlerFactory} for all tests in the annotated class.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@Documented
+@Inherited
+@ExtendWith(URLStreamHandlerFactoryExtension.class)
+@Isolated
+public @interface UsingURLStreamHandlerFactory {
+    Class<? extends URLStreamHandlerFactory> value();
+}
diff --git a/log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/util/ResolverUtilCustomProtocolTest.java b/log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/util/ResolverUtilCustomProtocolTest.java
index ecbc8381bf..6fa8437816 100644
--- a/log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/util/ResolverUtilCustomProtocolTest.java
+++ b/log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/util/ResolverUtilCustomProtocolTest.java
@@ -17,30 +17,31 @@
 
 package org.apache.logging.log4j.plugins.util;
 
-import org.apache.logging.log4j.test.junit.CleanFolders;
-import org.apache.logging.log4j.test.junit.URLStreamHandlerFactoryRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.RuleChain;
+import org.apache.logging.log4j.test.junit.UsingURLStreamHandlerFactory;
+import org.junit.jupiter.api.Test;
 
+import java.io.File;
 import java.io.IOException;
-import java.net.*;
-import java.util.Arrays;
+import java.net.Proxy;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
 import java.util.Collections;
 import java.util.Enumeration;
+import java.util.List;
 
-import static org.junit.Assert.assertEquals;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 /**
  * Tests the ResolverUtil class for custom protocol like bundleresource, vfs, vfszip.
  */
+@UsingURLStreamHandlerFactory(ResolverUtilCustomProtocolTest.NoopURLStreamHandlerFactory.class)
 public class ResolverUtilCustomProtocolTest {
 
-    @Rule
-    public URLStreamHandlerFactoryRule rule = new URLStreamHandlerFactoryRule(new NoopURLStreamHandlerFactory());
-
-    @Rule
-    public RuleChain chain = RuleChain.outerRule(new CleanFolders(ResolverUtilTest.WORK_DIR));
+    static final String WORK_DIR = "target/testpluginsutil";
 
     static class NoopURLStreamHandlerFactory implements URLStreamHandlerFactory {
 
@@ -103,7 +104,7 @@ public class ResolverUtilCustomProtocolTest {
 
         @Override
         protected Enumeration<URL> findResources(final String name) throws IOException {
-            return Collections.enumeration(Arrays.asList(findResource(name)));
+            return Collections.enumeration(List.of(findResource(name)));
         }
     }
 
@@ -177,27 +178,23 @@ public class ResolverUtilCustomProtocolTest {
 
     @Test
     public void testFindInPackageFromVfsDirectoryURL() throws Exception {
-        try (final URLClassLoader cl = ResolverUtilTest.compileAndCreateClassLoader("3")) {
+        try (final URLClassLoader cl = ResolverUtilTest.compileAndCreateClassLoader("3", new File(WORK_DIR))) {
             final ResolverUtil resolverUtil = new ResolverUtil();
             resolverUtil
-                    .setClassLoader(new SingleURLClassLoader(new URL("vfs:/" + ResolverUtilTest.WORK_DIR + "/resolverutil3/customplugin3/"), cl));
+                    .setClassLoader(new SingleURLClassLoader(new URL("vfs:/" + WORK_DIR + "/resolverutil3/customplugin3/"), cl));
             resolverUtil.findInPackage(new PluginRegistry.PluginTest(), "customplugin3");
-            assertEquals("Class not found in packages", 1, resolverUtil.getClasses().size());
-            assertEquals("Unexpected class resolved", cl.loadClass("customplugin3.FixedString3"),
-                    resolverUtil.getClasses().iterator().next());
+            assertThat(resolverUtil.getClasses()).containsOnly(cl.loadClass("customplugin3.FixedString3"));
         }
     }
 
     @Test
     public void testFindInPackageFromVfsJarURL() throws Exception {
-        try (final URLClassLoader cl = ResolverUtilTest.compileJarAndCreateClassLoader("4")) {
+        try (final URLClassLoader cl = ResolverUtilTest.compileJarAndCreateClassLoader("4", new File(WORK_DIR))) {
             final ResolverUtil resolverUtil = new ResolverUtil();
             resolverUtil.setClassLoader(new SingleURLClassLoader(
-                    new URL("vfs:/" + ResolverUtilTest.WORK_DIR + "/resolverutil4/customplugin4.jar/customplugin4/"), cl));
+                    new URL("vfs:/" + WORK_DIR + "/resolverutil4/customplugin4.jar/customplugin4/"), cl));
             resolverUtil.findInPackage(new PluginRegistry.PluginTest(), "customplugin4");
-            assertEquals("Class not found in packages", 1, resolverUtil.getClasses().size());
-            assertEquals("Unexpected class resolved", cl.loadClass("customplugin4.FixedString4"),
-                    resolverUtil.getClasses().iterator().next());
+            assertThat(resolverUtil.getClasses()).containsOnly(cl.loadClass("customplugin4.FixedString4"));
         }
     }
 
diff --git a/log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/util/ResolverUtilTest.java b/log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/util/ResolverUtilTest.java
index 642559111d..912f686803 100644
--- a/log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/util/ResolverUtilTest.java
+++ b/log4j-plugins-test/src/test/java/org/apache/logging/log4j/plugins/util/ResolverUtilTest.java
@@ -17,33 +17,42 @@
 
 package org.apache.logging.log4j.plugins.util;
 
-import org.apache.logging.log4j.test.junit.CleanFolders;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.RuleChain;
-
-import javax.tools.*;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
 import java.io.File;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
-import java.net.*;
-import java.nio.file.*;
-import java.util.*;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertNotNull;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.*;
 
 /**
  * Tests the ResolverUtil class.
  */
 public class ResolverUtilTest {
 
-    static final String WORK_DIR = "target/testpluginsutil";
-
-    @Rule
-    public RuleChain chain = RuleChain.outerRule(new CleanFolders(WORK_DIR));
-
     @Test
     public void testExtractPathFromJarUrl() throws Exception {
         final URL url = new URL("jar:file:/C:/Users/me/.m2/repository/junit/junit/4.11/junit-4.11.jar!/org/junit/Test.class");
@@ -59,13 +68,13 @@ public class ResolverUtilTest {
     private void testExtractPathFromJarUrlNotDecodedIfFileExists(final String existingFile)
             throws MalformedURLException, UnsupportedEncodingException, URISyntaxException {
         URL url = ResolverUtilTest.class.getResource(existingFile);
-        assertNotNull("No url returned for " + existingFile, url);
+        assertNotNull(url, "No url returned for " + existingFile);
         if (!url.getProtocol().equals("jar")) {
             // create fake jar: URL that resolves to existing file
             url = new URL("jar:" + url.toExternalForm() + "!/some/entry");
         }
         final String actual = new ResolverUtil().extractPath(url);
-        assertTrue("should not be decoded: " + actual, actual.endsWith(existingFile));
+        assertTrue(actual.endsWith(existingFile), "should not be decoded: " + actual);
     }
 
     @Test
@@ -92,10 +101,11 @@ public class ResolverUtilTest {
     public void testExtractPathFromFileUrlNotDecodedIfFileExists() throws Exception {
         final String existingFile = "/log4j+config+with+plus+characters.xml";
         final URL url = ResolverUtilTest.class.getResource(existingFile);
-        assertTrue("should be file url but was " + url, "file".equals(url.getProtocol()));
+        assertNotNull(url);
+        assertEquals("file", url.getProtocol(), "should be file url but was " + url);
 
         final String actual = new ResolverUtil().extractPath(url);
-        assertTrue("should not be decoded: " + actual, actual.endsWith(existingFile));
+        assertTrue(actual.endsWith(existingFile), "should not be decoded: " + actual);
     }
 
     @Test
@@ -141,31 +151,29 @@ public class ResolverUtilTest {
     }
 
     @Test
-    public void testFindInPackageFromDirectoryPath() throws Exception {
-        try (final URLClassLoader cl = compileAndCreateClassLoader("1")) {
+    public void testFindInPackageFromDirectoryPath(@TempDir final File baseDir) throws Exception {
+        try (final URLClassLoader cl = compileAndCreateClassLoader("1", baseDir)) {
             final ResolverUtil resolverUtil = new ResolverUtil();
             resolverUtil.setClassLoader(cl);
             resolverUtil.findInPackage(new PluginRegistry.PluginTest(), "customplugin1");
-            assertEquals("Class not found in packages", 1, resolverUtil.getClasses().size());
-            assertEquals("Unexpected class resolved", cl.loadClass("customplugin1.FixedString1"),
-                    resolverUtil.getClasses().iterator().next());
+            assertEquals(1, resolverUtil.getClasses().size(), "Class not found in packages");
+            assertEquals(cl.loadClass("customplugin1.FixedString1"), resolverUtil.getClasses().iterator().next(), "Unexpected class resolved");
         }
     }
 
     @Test
-    public void testFindInPackageFromJarPath() throws Exception {
-        try (final URLClassLoader cl = compileJarAndCreateClassLoader("2")) {
+    public void testFindInPackageFromJarPath(@TempDir final File baseDir) throws Exception {
+        try (final URLClassLoader cl = compileJarAndCreateClassLoader("2", baseDir)) {
             final ResolverUtil resolverUtil = new ResolverUtil();
             resolverUtil.setClassLoader(cl);
             resolverUtil.findInPackage(new PluginRegistry.PluginTest(), "customplugin2");
-            assertEquals("Class not found in packages", 1, resolverUtil.getClasses().size());
-            assertEquals("Unexpected class resolved", cl.loadClass("customplugin2.FixedString2"),
-                    resolverUtil.getClasses().iterator().next());
+            assertEquals(1, resolverUtil.getClasses().size(), "Class not found in packages");
+            assertEquals(cl.loadClass("customplugin2.FixedString2"), resolverUtil.getClasses().iterator().next(), "Unexpected class resolved");
         }
     }
 
-    static URLClassLoader compileJarAndCreateClassLoader(final String suffix) throws IOException, Exception {
-        final File workDir = compile(suffix);
+    static URLClassLoader compileJarAndCreateClassLoader(final String suffix, final File baseDir) throws IOException {
+        final File workDir = compile(suffix, baseDir);
         final File jarFile = new File(workDir, "customplugin" + suffix + ".jar");
         final URI jarURI = jarFile.toURI();
         createJar(jarURI, workDir, new File(workDir,
@@ -173,18 +181,18 @@ public class ResolverUtilTest {
         return URLClassLoader.newInstance(new URL[] {jarURI.toURL()});
     }
 
-    static URLClassLoader compileAndCreateClassLoader(final String suffix) throws IOException {
-        final File workDir = compile(suffix);
+    static URLClassLoader compileAndCreateClassLoader(final String suffix, final File baseDir) throws IOException {
+        final File workDir = compile(suffix, baseDir);
         return URLClassLoader.newInstance(new URL[] {workDir.toURI().toURL()});
     }
 
-    static File compile(final String suffix) throws IOException {
+    static File compile(final String suffix, final File baseDir) throws IOException {
         final File orig = new File("target/test-classes/customplugin/FixedString.java.source");
-        final File workDir = new File(WORK_DIR, "resolverutil" + suffix);
+        final File workDir = new File(baseDir, "resolverutil" + suffix);
         final File f = new File(workDir, "customplugin" + suffix + "/FixedString" + suffix + ".java");
         final File parent = f.getParentFile();
         if (!parent.exists()) {
-          assertTrue("Create customplugin" + suffix + " folder KO", f.getParentFile().mkdirs());
+          assertTrue(f.getParentFile().mkdirs(), "Create customplugin" + suffix + " folder KO");
         }
 
         final String content = new String(Files.readAllBytes(orig.toPath()))
@@ -196,7 +204,7 @@ public class ResolverUtilTest {
         return workDir;
     }
 
-    static void createJar(final URI jarURI, final File workDir, final File f) throws Exception {
+    static void createJar(final URI jarURI, final File workDir, final File f) throws IOException {
         final Map<String, String> env = new HashMap<>();
         env.put("create", "true");
         final URI uri = URI.create("jar:file://" + jarURI.getRawPath());
@@ -217,12 +225,11 @@ public class ResolverUtilTest {
         final DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
         final List<String> errors = new ArrayList<>();
         try (final StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null)) {
-            final Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(Arrays
-                .asList(f));
+            final Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(List.of(f));
 
             // compile generated source
             // (switch off annotation processing: no need to create Log4j2Plugins.dat)
-            final List<String> options = Arrays.asList("-proc:none");
+            final List<String> options = List.of("-proc:none");
             compiler.getTask(null, fileManager, diagnostics, options, null, compilationUnits).call();
 
             // check we don't have any compilation errors
@@ -233,10 +240,7 @@ public class ResolverUtilTest {
                 }
             }
         }
-        if (!errors.isEmpty()) {
-            System.err.println("Compilatoin of " + f.getAbsolutePath() + " failed");
-        }
-        assertTrue(errors.toString(), errors.isEmpty());
+        assertThat(errors).isEmpty();
     }
 
 }