From e76475afed1f55f75c1635fb696a9eca605eebf7 Mon Sep 17 00:00:00 2001 From: Holly Cummins Date: Wed, 15 Jan 2025 09:55:24 +0000 Subject: [PATCH] Revert "Hackily force use of FacadeLoader as TCCL in multimodule tests" This reverts commit 73c1dd40ec62eb0668695fd118e1fd8b4ef3fe6d. --- .../classloading/QuarkusClassLoader.java | 56 +++++-------------- .../AbstractJvmQuarkusTestExtension.java | 38 ++----------- 2 files changed, 19 insertions(+), 75 deletions(-) diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/QuarkusClassLoader.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/QuarkusClassLoader.java index 960050e364269..c7ae772232615 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/QuarkusClassLoader.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/QuarkusClassLoader.java @@ -55,15 +55,10 @@ public class QuarkusClassLoader extends ClassLoader implements Closeable { registerAsParallelCapable(); } - private ClassLoader facade; - private static RuntimeException nonQuarkusClassLoaderError() { return new IllegalStateException("The current classloader is not an instance of " + QuarkusClassLoader.class.getName() + " but " - + Thread.currentThread() - .getContextClassLoader() - .getClass() - .getName()); + + Thread.currentThread().getContextClassLoader().getClass().getName()); } /** @@ -77,8 +72,7 @@ private static RuntimeException nonQuarkusClassLoaderError() { * @param visitor runtime resource visitor */ public static void visitRuntimeResources(String resourceName, Consumer visitor) { - if (Thread.currentThread() - .getContextClassLoader() instanceof QuarkusClassLoader classLoader) { + if (Thread.currentThread().getContextClassLoader() instanceof QuarkusClassLoader classLoader) { for (var element : classLoader.getElementsWithResource(resourceName)) { if (element.isRuntime()) { element.apply(tree -> { @@ -93,8 +87,7 @@ public static void visitRuntimeResources(String resourceName, Consumer getElements(String resourceName, boolean onlyFromCurrentClassLoader) { - if (Thread.currentThread() - .getContextClassLoader() instanceof QuarkusClassLoader classLoader) { + if (Thread.currentThread().getContextClassLoader() instanceof QuarkusClassLoader classLoader) { return classLoader.getElementsWithResource(resourceName, onlyFromCurrentClassLoader); } throw nonQuarkusClassLoaderError(); @@ -114,8 +107,7 @@ public static boolean isClassPresentAtRuntime(String className) { * Indicates if a given class is considered an application class. */ public static boolean isApplicationClass(String className) { - if (Thread.currentThread() - .getContextClassLoader() instanceof QuarkusClassLoader classLoader) { + if (Thread.currentThread().getContextClassLoader() instanceof QuarkusClassLoader classLoader) { String resourceName = fromClassNameToResourceName(className); ClassPathResourceIndex classPathResourceIndex = classLoader.getClassPathResourceIndex(); @@ -134,8 +126,7 @@ public static boolean isApplicationClass(String className) { public static boolean isResourcePresentAtRuntime(String resourcePath) { List classPathElements = QuarkusClassLoader.getElements(resourcePath, false); for (int i = 0; i < classPathElements.size(); i++) { - if (classPathElements.get(i) - .isRuntime()) { + if (classPathElements.get(i).isRuntime()) { return true; } } @@ -181,8 +172,7 @@ public static boolean isResourcePresentAtRuntime(String resourcePath) { static { ClassLoader cl = null; try { - cl = (ClassLoader) ClassLoader.class.getDeclaredMethod("getPlatformClassLoader") - .invoke(null); + cl = (ClassLoader) ClassLoader.class.getDeclaredMethod("getPlatformClassLoader").invoke(null); } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { } @@ -196,9 +186,6 @@ private QuarkusClassLoader(Builder builder) { // Not passing the name to the parent constructor on purpose: // stacktraces become very ugly if we do that. super(builder.parent); - - this.facade = Thread.currentThread().getContextClassLoader(); - this.name = builder.name; this.status = STATUS_OPEN; this.normalPriorityElements = builder.normalPriorityElements; @@ -262,8 +249,7 @@ public Enumeration getResources(String unsanitisedName, boolean parentAlrea ensureOpen(unsanitisedName); for (int i = 0; i < classLoaderEventListeners.size(); i++) { - classLoaderEventListeners.get(i) - .enumeratingResourceURLs(unsanitisedName, this.name); + classLoaderEventListeners.get(i).enumeratingResourceURLs(unsanitisedName, this.name); } ClassPathResourceIndex classPathResourceIndex = getClassPathResourceIndex(); String name = sanitizeName(unsanitisedName); @@ -298,8 +284,7 @@ public Enumeration getResources(String unsanitisedName, boolean parentAlrea if (!classPathElements.isEmpty()) { boolean endsWithTrailingSlash = unsanitisedName.endsWith("/"); for (int i = 0; i < classPathElements.size(); i++) { - List resList = classPathElements.get(i) - .getResources(name); + List resList = classPathElements.get(i).getResources(name); //if the requested name ends with a trailing / we make sure //that the resource is a directory, and return a URL that ends with a / //this matches the behaviour of URLClassLoader @@ -308,8 +293,7 @@ public Enumeration getResources(String unsanitisedName, boolean parentAlrea if (endsWithTrailingSlash) { if (res.isDirectory()) { try { - resources.add(new URL(res.getUrl() - .toString() + "/")); + resources.add(new URL(res.getUrl().toString() + "/")); } catch (MalformedURLException e) { throw new RuntimeException(e); } @@ -419,8 +403,7 @@ public URL getResource(String unsanitisedName) { private static URL getClassPathElementResourceUrl(List classPathElements, String name, boolean endsWithTrailingSlash) { for (int i = 0; i < classPathElements.size(); i++) { - ClassPathResource res = classPathElements.get(i) - .getResource(name); + ClassPathResource res = classPathElements.get(i).getResource(name); if (res != null) { //if the requested name ends with a trailing / we make sure //that the resource is a directory, and return a URL that ends with a / @@ -428,8 +411,7 @@ private static URL getClassPathElementResourceUrl(List classPa if (endsWithTrailingSlash) { if (res.isDirectory()) { try { - return new URL(res.getUrl() - .toString() + "/"); + return new URL(res.getUrl().toString() + "/"); } catch (MalformedURLException e) { throw new RuntimeException(e); } @@ -448,8 +430,7 @@ public InputStream getResourceAsStream(String unsanitisedName) { ensureOpen(unsanitisedName); for (int i = 0; i < classLoaderEventListeners.size(); i++) { - classLoaderEventListeners.get(i) - .openResourceStream(unsanitisedName, this.name); + classLoaderEventListeners.get(i).openResourceStream(unsanitisedName, this.name); } String name = sanitizeName(unsanitisedName); ClassPathResourceIndex classPathResourceIndex = getClassPathResourceIndex(); @@ -487,8 +468,7 @@ private static InputStream getClassPathElementResourceInputStream(List loadClass(String name, boolean resolve) throws ClassNotFoundE } finally { if (interrupted) { //restore interrupt state - Thread.currentThread() - .interrupt(); + Thread.currentThread().interrupt(); } } } @@ -787,8 +766,7 @@ public void close() { try (InputStream is = getClass().getResourceAsStream("DriverRemover.class")) { byte[] data = is.readAllBytes(); Runnable r = (Runnable) defineClass(DriverRemover.class.getName(), data, 0, data.length) - .getConstructor(ClassLoader.class) - .newInstance(this); + .getConstructor(ClassLoader.class).newInstance(this); r.run(); } catch (Exception e) { log.debug("Failed to clean up DB drivers"); @@ -856,10 +834,6 @@ public void setStartupAction(StartupAction startupAction) { this.startupAction = startupAction; } - public ClassLoader getFacadeClassloader() { - return facade; - } - public static class Builder { final String name; final ClassLoader parent; diff --git a/test-framework/junit5/src/main/java/io/quarkus/test/junit/AbstractJvmQuarkusTestExtension.java b/test-framework/junit5/src/main/java/io/quarkus/test/junit/AbstractJvmQuarkusTestExtension.java index 068c3f983fb88..d77f47960f227 100644 --- a/test-framework/junit5/src/main/java/io/quarkus/test/junit/AbstractJvmQuarkusTestExtension.java +++ b/test-framework/junit5/src/main/java/io/quarkus/test/junit/AbstractJvmQuarkusTestExtension.java @@ -48,8 +48,6 @@ public class AbstractJvmQuarkusTestExtension extends AbstractQuarkusTestWithCont protected ClassLoader originalCl; - protected final ClassLoader facade; - // Used to preserve state from the previous run, so we know if we should restart an application protected static RunningQuarkusApplication runningQuarkusApplication; @@ -59,11 +57,6 @@ public class AbstractJvmQuarkusTestExtension extends AbstractQuarkusTestWithCont protected static final Deque> currentTestClassStack = new ArrayDeque<>(); protected static Class currentJUnitTestClass; - protected AbstractJvmQuarkusTestExtension() { - // TODO where is right place to get this? - facade = Thread.currentThread().getContextClassLoader(); - } - // TODO only used by QuarkusMainTest, fix that class and delete this protected PrepareResult createAugmentor(ExtensionContext context, Class profile, Collection shutdownTasks) throws Exception { @@ -268,44 +261,21 @@ public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext con System.out.println("OK smallrye " + SmallRyeConfig.class.getClassLoader()); // TODO this should not be necessary, because we want the config provider to be for our class - ClassLoader original = Thread.currentThread().getContextClassLoader(); - - QuarkusClassLoader mecl = (QuarkusClassLoader) this.getClass().getClassLoader(); - ClassLoader facade = mecl.getFacadeClassloader(); - - // Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); + // ClassLoader original = Thread.currentThread().getContextClassLoader(); + // Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); // SmallRyeConfig config = ConfigProvider.getConfig().unwrap(SmallRyeConfig.class); // TestConfig testConfig = config.getConfigMapping(TestConfig.class); // At this point, the TCCL is the FacadeClassLoader; trying to do getConfig with that TCCL fails with java.util.ServiceConfigurationError: io.smallrye.config.SmallRyeConfigFactory: io.quarkus.runtime.configuration.QuarkusConfigFactory not a subtype // If we set the TCCL to be this.getClass().getClassLoader(), get config succeeds, but config.getConfigMapping(TestConfig.class) fails, because the mapping was registered when the TCCL was the FacadeClassLoader - // In nested tests and multimodule tests, the TCCL may not be the facade classloader - - // ClassLoader facade = FacadeClassLoader.instance(Exception.class.getClassLoader()); - // Thread.currentThread().setContextClassLoader(Error.class.getClassLoader()); - Thread.currentThread().setContextClassLoader(facade); - System.out.println("HOLLY Config using facade TCCL " + Thread.currentThread().getContextClassLoader()); - - TestConfig testConfig = null; - System.out.println("HOLLY CONFIG " + " and the class of the mapping is " - + TestConfig.class.getClassLoader()); - try { - testConfig = ConfigProvider.getConfig().unwrap(SmallRyeConfig.class).getConfigMapping(TestConfig.class); - } catch (RuntimeException | Error e) { - System.out.println("HOLLY Config DOOOOOOM " + e); - System.out.println("HOLLY Config TCCL is " + Thread.currentThread().getContextClassLoader() - + " and the class of the mapping is " - + TestConfig.class.getClassLoader()); - System.out.println("HOLLY Config my class is " + this.getClass().getClassLoader()); - throw e; - } + TestConfig testConfig = ConfigProvider.getConfig().unwrap(SmallRyeConfig.class).getConfigMapping(TestConfig.class); Optional> tags = testConfig.profile().tags(); if (tags.isEmpty() || tags.get().isEmpty()) { return ConditionEvaluationResult.enabled("No Quarkus Test Profile tags"); } - Thread.currentThread().setContextClassLoader(original); + // Thread.currentThread().setContextClassLoader(original); Class testProfile = getQuarkusTestProfile(context); if (testProfile == null) {