diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedDevModeMain.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedDevModeMain.java index 5096086bac47e..91730e752972c 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedDevModeMain.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedDevModeMain.java @@ -83,7 +83,7 @@ private synchronized void firstStart() { //this is a bit yuck, but we need replace the default //exit handler in the runtime class loader //TODO: look at implementing a common core classloader, that removes the need for this sort of crappy hack - curatedApplication.getBaseRuntimeClassLoader().loadClass(ApplicationLifecycleManager.class.getName()) + curatedApplication.getOrCreateBaseRuntimeClassLoader().loadClass(ApplicationLifecycleManager.class.getName()) .getMethod("setDefaultExitCodeHandler", Consumer.class) .invoke(null, new Consumer() { @Override @@ -139,7 +139,8 @@ public void accept(Integer integer) { ApplicationStateNotification.notifyStartupFailed(t); if (RuntimeUpdatesProcessor.INSTANCE != null) { - Thread.currentThread().setContextClassLoader(curatedApplication.getBaseRuntimeClassLoader()); + Thread.currentThread() + .setContextClassLoader(curatedApplication.getOrCreateBaseRuntimeClassLoader()); try { if (!InitialConfigurator.DELAYED_HANDLER.isActivated()) { Class cl = Thread.currentThread().getContextClassLoader() @@ -184,7 +185,7 @@ public synchronized void restartApp(Set changedResources, ClassChangeInf consoleContext.reset(); } stop(); - Timing.restart(curatedApplication.getAugmentClassLoader()); + Timing.restart(curatedApplication.getOrCreateAugmentClassLoader()); deploymentProblem = null; ClassLoader old = Thread.currentThread().getContextClassLoader(); try { @@ -206,7 +207,7 @@ public synchronized void restartApp(Set changedResources, ClassChangeInf } if (!(rootCause instanceof BindException)) { log.error("Failed to start quarkus", t); - Thread.currentThread().setContextClassLoader(curatedApplication.getAugmentClassLoader()); + Thread.currentThread().setContextClassLoader(curatedApplication.getOrCreateAugmentClassLoader()); LoggingSetupRecorder.handleFailedStart(); } } @@ -255,19 +256,19 @@ public byte[] apply(String s, byte[] bytes) { }, testSupport); for (HotReplacementSetup service : ServiceLoader.load(HotReplacementSetup.class, - curatedApplication.getBaseRuntimeClassLoader())) { + curatedApplication.getOrCreateBaseRuntimeClassLoader())) { hotReplacementSetups.add(service); service.setupHotDeployment(processor); processor.addHotReplacementSetup(service); } for (DeploymentFailedStartHandler service : ServiceLoader.load(DeploymentFailedStartHandler.class, - curatedApplication.getAugmentClassLoader())) { + curatedApplication.getOrCreateAugmentClassLoader())) { processor.addDeploymentFailedStartHandler(new Runnable() { @Override public void run() { ClassLoader old = Thread.currentThread().getContextClassLoader(); try { - Thread.currentThread().setContextClassLoader(curatedApplication.getAugmentClassLoader()); + Thread.currentThread().setContextClassLoader(curatedApplication.getOrCreateAugmentClassLoader()); service.handleFailedInitialStart(); } finally { Thread.currentThread().setContextClassLoader(old); @@ -365,7 +366,7 @@ public void accept(CuratedApplication o, Map params) { //setup the dev mode thread pool for NIO System.setProperty("java.nio.channels.DefaultThreadPool.threadFactory", "io.quarkus.dev.io.NioThreadPoolThreadFactory"); - Timing.staticInitStarted(o.getBaseRuntimeClassLoader(), false); + Timing.staticInitStarted(o.getOrCreateBaseRuntimeClassLoader(), false); //https://github.com/quarkusio/quarkus/issues/9748 //if you have an app with all daemon threads then the app thread //may be the only thread keeping the JVM alive diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedRemoteDevModeMain.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedRemoteDevModeMain.java index 1ec369cd140fb..a1e691f0748ed 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedRemoteDevModeMain.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedRemoteDevModeMain.java @@ -68,7 +68,7 @@ public class IsolatedRemoteDevModeMain implements BiConsumer providers = ServiceLoader.load(RemoteDevClientProvider.class, - curatedApplication.getAugmentClassLoader()); + curatedApplication.getOrCreateAugmentClassLoader()); RemoteDevClient client = null; for (RemoteDevClientProvider provider : providers) { Optional opt = provider.getClient(); @@ -140,19 +140,19 @@ public byte[] apply(String s, byte[] bytes) { }, null); for (HotReplacementSetup service : ServiceLoader.load(HotReplacementSetup.class, - curatedApplication.getBaseRuntimeClassLoader())) { + curatedApplication.getOrCreateBaseRuntimeClassLoader())) { hotReplacementSetups.add(service); service.setupHotDeployment(processor); processor.addHotReplacementSetup(service); } for (DeploymentFailedStartHandler service : ServiceLoader.load(DeploymentFailedStartHandler.class, - curatedApplication.getAugmentClassLoader())) { + curatedApplication.getOrCreateAugmentClassLoader())) { processor.addDeploymentFailedStartHandler(new Runnable() { @Override public void run() { ClassLoader old = Thread.currentThread().getContextClassLoader(); try { - Thread.currentThread().setContextClassLoader(curatedApplication.getAugmentClassLoader()); + Thread.currentThread().setContextClassLoader(curatedApplication.getOrCreateAugmentClassLoader()); service.handleFailedInitialStart(); } finally { Thread.currentThread().setContextClassLoader(old); @@ -198,7 +198,7 @@ public void close() { @Override public void accept(CuratedApplication o, Map o2) { LoggingSetupRecorder.handleFailedStart(); //we are not going to actually run an app - Timing.staticInitStarted(o.getBaseRuntimeClassLoader(), false); + Timing.staticInitStarted(o.getOrCreateBaseRuntimeClassLoader(), false); try { curatedApplication = o; Object potentialContext = o2.get(DevModeContext.class.getName()); diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedTestModeMain.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedTestModeMain.java index e58029cd79cf2..1f5b37aa311f0 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedTestModeMain.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedTestModeMain.java @@ -71,7 +71,7 @@ public byte[] apply(String s, byte[] bytes) { }, testSupport); for (HotReplacementSetup service : ServiceLoader.load(HotReplacementSetup.class, - curatedApplication.getBaseRuntimeClassLoader())) { + curatedApplication.getOrCreateBaseRuntimeClassLoader())) { hotReplacementSetups.add(service); service.setupHotDeployment(processor); processor.addHotReplacementSetup(service); @@ -107,7 +107,7 @@ public void close() { public void accept(CuratedApplication o, Map params) { System.setProperty("java.nio.channels.DefaultThreadPool.threadFactory", "io.quarkus.dev.io.NioThreadPoolThreadFactory"); - Timing.staticInitStarted(o.getBaseRuntimeClassLoader(), false); + Timing.staticInitStarted(o.getOrCreateBaseRuntimeClassLoader(), false); try { curatedApplication = o; Object potentialContext = params.get(DevModeContext.class.getName()); diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/ModuleTestRunner.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/ModuleTestRunner.java index be0ca21445bf0..228665b40573f 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/ModuleTestRunner.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/testing/ModuleTestRunner.java @@ -40,7 +40,7 @@ public synchronized void abort() { Runnable prepare(ClassScanResult classScanResult, boolean reRunFailures, long runId, TestRunListener listener) { var old = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(testApplication.getAugmentClassLoader()); + Thread.currentThread().setContextClassLoader(testApplication.getOrCreateAugmentClassLoader()); try { synchronized (this) { if (runner != null) { @@ -84,7 +84,7 @@ public FilterResult apply(TestDescriptor testDescriptor) { @Override public void run() { var old = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(testApplication.getAugmentClassLoader()); + Thread.currentThread().setContextClassLoader(testApplication.getOrCreateAugmentClassLoader()); try { prepared.run(); } finally { diff --git a/core/deployment/src/main/java/io/quarkus/deployment/jbang/JBangAugmentorImpl.java b/core/deployment/src/main/java/io/quarkus/deployment/jbang/JBangAugmentorImpl.java index 40b2b0f3f8a23..4fe1d0469bd19 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/jbang/JBangAugmentorImpl.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/jbang/JBangAugmentorImpl.java @@ -40,7 +40,7 @@ public class JBangAugmentorImpl implements BiConsumer resultMap) { - QuarkusClassLoader classLoader = curatedApplication.getAugmentClassLoader(); + QuarkusClassLoader classLoader = curatedApplication.getOrCreateAugmentClassLoader(); try (QuarkusClassLoader deploymentClassLoader = curatedApplication.createDeploymentClassLoader()) { QuarkusBootstrap quarkusBootstrap = curatedApplication.getQuarkusBootstrap(); diff --git a/core/deployment/src/main/java/io/quarkus/runner/bootstrap/AugmentActionImpl.java b/core/deployment/src/main/java/io/quarkus/runner/bootstrap/AugmentActionImpl.java index 43776e45eba47..af2bb2e33d1d1 100644 --- a/core/deployment/src/main/java/io/quarkus/runner/bootstrap/AugmentActionImpl.java +++ b/core/deployment/src/main/java/io/quarkus/runner/bootstrap/AugmentActionImpl.java @@ -277,7 +277,7 @@ private BuildResult runAugment(boolean firstRun, Set changedResources, Class... finalOutputs) { ClassLoader old = Thread.currentThread().getContextClassLoader(); try { - QuarkusClassLoader classLoader = curatedApplication.getAugmentClassLoader(); + QuarkusClassLoader classLoader = curatedApplication.getOrCreateAugmentClassLoader(); Thread.currentThread().setContextClassLoader(classLoader); LaunchMode.set(launchMode); diff --git a/core/deployment/src/main/java/io/quarkus/runner/bootstrap/StartupActionImpl.java b/core/deployment/src/main/java/io/quarkus/runner/bootstrap/StartupActionImpl.java index 57f575edbf18a..4589a5d5407c7 100644 --- a/core/deployment/src/main/java/io/quarkus/runner/bootstrap/StartupActionImpl.java +++ b/core/deployment/src/main/java/io/quarkus/runner/bootstrap/StartupActionImpl.java @@ -64,7 +64,7 @@ public StartupActionImpl(CuratedApplication curatedApplication, BuildResult buil this.runtimeApplicationShutdownBuildItems = buildResult.consumeMulti(RuntimeApplicationShutdownBuildItem.class); Map transformedClasses = extractTransformedClasses(buildResult); - QuarkusClassLoader baseClassLoader = curatedApplication.getBaseRuntimeClassLoader(); + QuarkusClassLoader baseClassLoader = curatedApplication.getOrCreateBaseRuntimeClassLoader(); QuarkusClassLoader runtimeClassLoader; //so we have some differences between dev and test mode here. 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 db443557934e4..7b66d6c856413 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 @@ -90,7 +90,7 @@ public QuarkusBootstrap getQuarkusBootstrap() { } public Object runInAugmentClassLoader(String consumerName, Map params) { - return runInCl(consumerName, params, getAugmentClassLoader()); + return runInCl(consumerName, params, getOrCreateAugmentClassLoader()); } public CurationResult getCurationResult() { @@ -99,7 +99,7 @@ public CurationResult getCurationResult() { public AugmentAction createAugmentor() { try { - Class augmentor = getAugmentClassLoader().loadClass(AUGMENTOR); + Class augmentor = getOrCreateAugmentClassLoader().loadClass(AUGMENTOR); return (AugmentAction) augmentor.getConstructor(CuratedApplication.class).newInstance(this); } catch (Exception e) { throw new RuntimeException(e); @@ -115,8 +115,8 @@ public AugmentAction createAugmentor() { */ public AugmentAction createAugmentor(String functionName, Map props) { try { - Class augmentor = getAugmentClassLoader().loadClass(AUGMENTOR); - Function> function = (Function>) getAugmentClassLoader() + Class augmentor = getOrCreateAugmentClassLoader().loadClass(AUGMENTOR); + Function> function = (Function>) getOrCreateAugmentClassLoader() .loadClass(functionName) .getDeclaredConstructor() .newInstance(); @@ -189,7 +189,7 @@ private void addCpElement(QuarkusClassLoader.Builder builder, ResolvedDependency builder.addElement(element); } - public synchronized QuarkusClassLoader getAugmentClassLoader() { + public synchronized QuarkusClassLoader getOrCreateAugmentClassLoader() { if (augmentClassLoader == null) { //first run, we need to build all the class loaders QuarkusClassLoader.Builder builder = QuarkusClassLoader.builder( @@ -226,6 +226,14 @@ public synchronized QuarkusClassLoader getAugmentClassLoader() { return augmentClassLoader; } + /** + * In most cases {@link #getOrCreateAugmentClassLoader()} should be used but this can be useful if you want to be able to + * get this instance without creating it (and so potentially get null if it doesn't exist). + */ + public QuarkusClassLoader getAugmentClassLoader() { + return augmentClassLoader; + } + /** * creates the base runtime class loader. * @@ -235,7 +243,7 @@ public synchronized QuarkusClassLoader getAugmentClassLoader() { * as each startup can generate new resources. * */ - public synchronized QuarkusClassLoader getBaseRuntimeClassLoader() { + public synchronized QuarkusClassLoader getOrCreateBaseRuntimeClassLoader() { if (baseRuntimeClassLoader == null) { QuarkusClassLoader.Builder builder = QuarkusClassLoader.builder( "Quarkus Base Runtime ClassLoader: " + quarkusBootstrap.getMode() + getClassLoaderNameSuffix(), @@ -304,6 +312,14 @@ public synchronized QuarkusClassLoader getBaseRuntimeClassLoader() { return baseRuntimeClassLoader; } + /** + * In most cases {@link #getOrCreateBaseRuntimeClassLoader()} should be used but this can be useful if you want to be able + * to get this instance without creating it (and so potentially get null if it doesn't exist). + */ + public QuarkusClassLoader getBaseRuntimeClassLoader() { + return baseRuntimeClassLoader; + } + private static boolean isHotReloadable(ResolvedDependency a, Set hotReloadPaths) { for (Path p : a.getContentTree().getRoots()) { if (hotReloadPaths.contains(p)) { @@ -317,7 +333,7 @@ public QuarkusClassLoader createDeploymentClassLoader() { //first run, we need to build all the class loaders QuarkusClassLoader.Builder builder = QuarkusClassLoader .builder("Deployment Class Loader: " + quarkusBootstrap.getMode() + getClassLoaderNameSuffix(), - getAugmentClassLoader(), false) + getOrCreateAugmentClassLoader(), false) .addClassLoaderEventListeners(quarkusBootstrap.getClassLoaderEventListeners()) .setAssertionsEnabled(quarkusBootstrap.isAssertionsEnabled()) .setAggregateParentResources(true); @@ -355,7 +371,7 @@ public String getClassLoaderNameSuffix() { } public QuarkusClassLoader createRuntimeClassLoader(Map resources, Map transformedClasses) { - return createRuntimeClassLoader(getBaseRuntimeClassLoader(), resources, transformedClasses); + return createRuntimeClassLoader(getOrCreateBaseRuntimeClassLoader(), resources, transformedClasses); } public QuarkusClassLoader createRuntimeClassLoader(ClassLoader base, Map resources, @@ -366,7 +382,7 @@ public QuarkusClassLoader createRuntimeClassLoader(ClassLoader base, Map props = new HashMap<>(); props.put(TEST_LOCATION, testClassLocation); diff --git a/test-framework/junit5/src/main/java/io/quarkus/test/junit/IntegrationTestUtil.java b/test-framework/junit5/src/main/java/io/quarkus/test/junit/IntegrationTestUtil.java index b0e71f5e485b0..a29edfc4a0488 100644 --- a/test-framework/junit5/src/main/java/io/quarkus/test/junit/IntegrationTestUtil.java +++ b/test-framework/junit5/src/main/java/io/quarkus/test/junit/IntegrationTestUtil.java @@ -306,7 +306,7 @@ public void accept(String s, String s2) { // obtain the ID of the shared network - this needs to be done after the augmentation has been run // or else we run into various ClassLoader problems try { - Class networkClass = curatedApplication.getAugmentClassLoader() + Class networkClass = curatedApplication.getOrCreateAugmentClassLoader() .loadClass("org.testcontainers.containers.Network"); Object sharedNetwork = networkClass.getField("SHARED").get(null); networkId = (String) networkClass.getMethod("getId").invoke(sharedNetwork);