diff --git a/core/deployment/src/main/java/io/quarkus/deployment/steps/MainClassBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/steps/MainClassBuildStep.java index dd3074298b934..d821d43a49f22 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/steps/MainClassBuildStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/steps/MainClassBuildStep.java @@ -28,6 +28,7 @@ import io.quarkus.bootstrap.logging.InitialConfigurator; import io.quarkus.bootstrap.logging.QuarkusDelayedHandler; +import io.quarkus.bootstrap.naming.DisabledInitialContextManager; import io.quarkus.bootstrap.runner.Timing; import io.quarkus.builder.Version; import io.quarkus.deployment.GeneratedClassGizmoAdaptor; @@ -83,7 +84,6 @@ import io.quarkus.runtime.appcds.AppCDSUtil; import io.quarkus.runtime.configuration.ConfigUtils; import io.quarkus.runtime.configuration.ProfileManager; -import io.quarkus.runtime.naming.DisabledInitialContextManager; import io.quarkus.runtime.util.StepTiming; public class MainClassBuildStep { diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/CuratedApplication.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/CuratedApplication.java index 9b5d41d029b33..d51837e39e399 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/CuratedApplication.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/app/CuratedApplication.java @@ -405,9 +405,11 @@ public boolean hasReloadableArtifacts() { public void close() { if (augmentClassLoader != null) { augmentClassLoader.close(); + augmentClassLoader = null; } if (baseRuntimeClassLoader != null) { baseRuntimeClassLoader.close(); + baseRuntimeClassLoader = null; } augmentationElements.clear(); } diff --git a/core/runtime/src/main/java/io/quarkus/runtime/naming/DisabledInitialContext.java b/independent-projects/bootstrap/runner/src/main/java/io/quarkus/bootstrap/naming/DisabledInitialContext.java similarity index 99% rename from core/runtime/src/main/java/io/quarkus/runtime/naming/DisabledInitialContext.java rename to independent-projects/bootstrap/runner/src/main/java/io/quarkus/bootstrap/naming/DisabledInitialContext.java index e047ae2841496..f17307093deff 100644 --- a/core/runtime/src/main/java/io/quarkus/runtime/naming/DisabledInitialContext.java +++ b/independent-projects/bootstrap/runner/src/main/java/io/quarkus/bootstrap/naming/DisabledInitialContext.java @@ -1,4 +1,4 @@ -package io.quarkus.runtime.naming; +package io.quarkus.bootstrap.naming; import java.util.Hashtable; @@ -22,8 +22,8 @@ /** * Initial context that won't allow you to actually do anything. - * - * As most Quarkus applications don't let you + *

+ * Used by Quarkus to disable JNDI. */ public class DisabledInitialContext extends InitialLdapContext { diff --git a/core/runtime/src/main/java/io/quarkus/runtime/naming/DisabledInitialContextManager.java b/independent-projects/bootstrap/runner/src/main/java/io/quarkus/bootstrap/naming/DisabledInitialContextManager.java similarity index 70% rename from core/runtime/src/main/java/io/quarkus/runtime/naming/DisabledInitialContextManager.java rename to independent-projects/bootstrap/runner/src/main/java/io/quarkus/bootstrap/naming/DisabledInitialContextManager.java index 464d8c5ced4e8..c192099f11508 100644 --- a/core/runtime/src/main/java/io/quarkus/runtime/naming/DisabledInitialContextManager.java +++ b/independent-projects/bootstrap/runner/src/main/java/io/quarkus/bootstrap/naming/DisabledInitialContextManager.java @@ -1,4 +1,4 @@ -package io.quarkus.runtime.naming; +package io.quarkus.bootstrap.naming; import java.util.Hashtable; @@ -8,6 +8,14 @@ import javax.naming.spi.InitialContextFactoryBuilder; import javax.naming.spi.NamingManager; +/** + * Delegate used by Quarkus to disable JNDI. + *

+ * This must be in a parent-first artifact as the initial context manager + * {@link NamingManager#setInitialContextFactoryBuilder(InitialContextFactoryBuilder) cannot be replaced} + * and will never get garbage-collected due to being referenced from a sticky class ({@link NamingManager}), + * so its classloader will never get garbage-collected either. + */ public class DisabledInitialContextManager implements InitialContextFactoryBuilder { public static synchronized void register() { diff --git a/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusUnitTest.java b/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusUnitTest.java index e7369ea65cee0..42d878b481e0a 100644 --- a/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusUnitTest.java +++ b/test-framework/junit5-internal/src/main/java/io/quarkus/test/QuarkusUnitTest.java @@ -119,6 +119,7 @@ public class QuarkusUnitTest private Runnable afterAllCustomizer; private CuratedApplication curatedApplication; private RunningQuarkusApplication runningQuarkusApplication; + private QuarkusClassLoader quarkusUnitTestClassLoader; private ClassLoader originalClassLoader; private List forcedDependencies = Collections.emptyList(); @@ -633,12 +634,11 @@ public boolean test(String s) { builder.setDisableClasspathCache(true); } if (!allowTestClassOutsideDeployment) { - builder - .setBaseClassLoader( - QuarkusClassLoader - .builder("QuarkusUnitTest ClassLoader", getClass().getClassLoader(), false) - .addClassLoaderEventListeners(this.classLoadListeners) - .addBannedElement(ClassPathElement.fromPath(testLocation, true)).build()); + quarkusUnitTestClassLoader = QuarkusClassLoader + .builder("QuarkusUnitTest ClassLoader", getClass().getClassLoader(), false) + .addClassLoaderEventListeners(this.classLoadListeners) + .addBannedElement(ClassPathElement.fromPath(testLocation, true)).build(); + builder.setBaseClassLoader(quarkusUnitTestClassLoader); } builder.addClassLoaderEventListeners(this.classLoadListeners); @@ -748,6 +748,10 @@ public void afterAll(ExtensionContext extensionContext) throws Exception { System.clearProperty("test.url"); Thread.currentThread().setContextClassLoader(originalClassLoader); originalClassLoader = null; + if (quarkusUnitTestClassLoader != null) { + quarkusUnitTestClassLoader.close(); + quarkusUnitTestClassLoader = null; + } timeoutTask.cancel(); timeoutTask = null; timeoutTimer.cancel();