Skip to content

Commit

Permalink
Close the deployment CL in the creator when augmenting
Browse files Browse the repository at this point in the history
Currently, we pass the CL to something that will close it, rather than
controlling the lifecycle in the creator method.

This is an issue in native ITs:

java.lang.RuntimeException: java.lang.IllegalStateException: This class loader has been closed
	at io.quarkus.test.junit.QuarkusIntegrationTestExtension.throwBootFailureException(QuarkusIntegrationTestExtension.java:373)
	at io.quarkus.test.junit.QuarkusIntegrationTestExtension.beforeEach(QuarkusIntegrationTestExtension.java:117)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: java.lang.IllegalStateException: This class loader has been closed
	at io.quarkus.bootstrap.classloading.QuarkusClassLoader.ensureOpen(QuarkusClassLoader.java:716)
	at io.quarkus.bootstrap.classloading.QuarkusClassLoader.loadClass(QuarkusClassLoader.java:495)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:467)
	at io.quarkus.runner.bootstrap.AugmentActionImpl.performCustomBuild(AugmentActionImpl.java:158)
	at io.quarkus.test.junit.IntegrationTestUtil.handleDevServices(IntegrationTestUtil.java:297)
	at io.quarkus.test.junit.QuarkusIntegrationTestExtension.doProcessStart(QuarkusIntegrationTestExtension.java:199)
	at io.quarkus.test.junit.QuarkusIntegrationTestExtension.ensureStarted(QuarkusIntegrationTestExtension.java:169)
	at io.quarkus.test.junit.QuarkusIntegrationTestExtension.beforeAll(QuarkusIntegrationTestExtension.java:130)

Related to quarkusio#41233
  • Loading branch information
gsmet authored and holly-cummins committed Jul 31, 2024
1 parent fc6aff1 commit 1daa43b
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 143 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.quarkus.deployment;

import java.io.Closeable;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
Expand Down Expand Up @@ -181,9 +180,6 @@ public BuildResult run() throws Exception {
.releaseConfig(deploymentClassLoader);
} catch (Exception ignore) {

}
if (deploymentClassLoader instanceof Closeable) {
((Closeable) deploymentClassLoader).close();
}
Thread.currentThread().setContextClassLoader(originalClassLoader);
buildCloseables.close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,102 +42,106 @@ public void accept(CuratedApplication curatedApplication, Map<String, Object> re

QuarkusClassLoader classLoader = curatedApplication.getAugmentClassLoader();

QuarkusBootstrap quarkusBootstrap = curatedApplication.getQuarkusBootstrap();
QuarkusAugmentor.Builder builder = QuarkusAugmentor.builder()
.setRoot(quarkusBootstrap.getApplicationRoot())
.setClassLoader(classLoader)
.addFinal(ApplicationClassNameBuildItem.class)
.setTargetDir(quarkusBootstrap.getTargetDirectory())
.setDeploymentClassLoader(curatedApplication.createDeploymentClassLoader())
.setBuildSystemProperties(quarkusBootstrap.getBuildSystemProperties())
.setEffectiveModel(curatedApplication.getApplicationModel());
if (quarkusBootstrap.getBaseName() != null) {
builder.setBaseName(quarkusBootstrap.getBaseName());
}
if (quarkusBootstrap.getOriginalBaseName() != null) {
builder.setOriginalBaseName(quarkusBootstrap.getOriginalBaseName());
}

boolean auxiliaryApplication = curatedApplication.getQuarkusBootstrap().isAuxiliaryApplication();
builder.setAuxiliaryApplication(auxiliaryApplication);
builder.setAuxiliaryDevModeType(
curatedApplication.getQuarkusBootstrap().isHostApplicationIsTestOnly() ? DevModeType.TEST_ONLY
: (auxiliaryApplication ? DevModeType.LOCAL : null));
builder.setLaunchMode(LaunchMode.NORMAL);
builder.setRebuild(quarkusBootstrap.isRebuild());
builder.setLiveReloadState(
new LiveReloadBuildItem(false, Collections.emptySet(), new HashMap<>(), null));
for (AdditionalDependency i : quarkusBootstrap.getAdditionalApplicationArchives()) {
//this gets added to the class path either way
//but we only need to add it to the additional app archives
//if it is forced as an app archive
if (i.isForceApplicationArchive()) {
builder.addAdditionalApplicationArchive(i.getResolvedPaths());
try (QuarkusClassLoader deploymentClassLoader = curatedApplication.createDeploymentClassLoader()) {
QuarkusBootstrap quarkusBootstrap = curatedApplication.getQuarkusBootstrap();
QuarkusAugmentor.Builder builder = QuarkusAugmentor.builder()
.setRoot(quarkusBootstrap.getApplicationRoot())
.setClassLoader(classLoader)
.addFinal(ApplicationClassNameBuildItem.class)
.setTargetDir(quarkusBootstrap.getTargetDirectory())
.setDeploymentClassLoader(curatedApplication.createDeploymentClassLoader())
.setBuildSystemProperties(quarkusBootstrap.getBuildSystemProperties())
.setEffectiveModel(curatedApplication.getApplicationModel());
if (quarkusBootstrap.getBaseName() != null) {
builder.setBaseName(quarkusBootstrap.getBaseName());
}
}
builder.addBuildChainCustomizer(new Consumer<BuildChainBuilder>() {
@Override
public void accept(BuildChainBuilder builder) {
final BuildStepBuilder stepBuilder = builder.addBuildStep((ctx) -> {
ctx.produce(new ProcessInheritIODisabledBuildItem());
});
stepBuilder.produces(ProcessInheritIODisabledBuildItem.class).build();
if (quarkusBootstrap.getOriginalBaseName() != null) {
builder.setOriginalBaseName(quarkusBootstrap.getOriginalBaseName());
}
});
builder.excludeFromIndexing(quarkusBootstrap.getExcludeFromClassPath());
builder.addFinal(GeneratedClassBuildItem.class);
builder.addFinal(MainClassBuildItem.class);
builder.addFinal(GeneratedResourceBuildItem.class);
builder.addFinal(TransformedClassesBuildItem.class);
builder.addFinal(DeploymentResultBuildItem.class);
// note: quarkus.package.type is deprecated
boolean nativeRequested = "native".equals(System.getProperty("quarkus.package.type"))
|| "true".equals(System.getProperty("quarkus.native.enabled"));
boolean containerBuildRequested = Boolean.getBoolean("quarkus.container-image.build");
if (nativeRequested) {
builder.addFinal(NativeImageBuildItem.class);
}
if (containerBuildRequested) {
//TODO: this is a bit ugly
//we don't necessarily need these artifacts
//but if we include them it does mean that you can auto create docker images
//and deploy to kube etc
//for an ordinary build with no native and no docker this is a waste
builder.addFinal(ArtifactResultBuildItem.class);
}

try {
BuildResult buildResult = builder.build().run();
Map<String, byte[]> result = new HashMap<>();
for (GeneratedClassBuildItem i : buildResult.consumeMulti(GeneratedClassBuildItem.class)) {
result.put(i.getName().replace(".", "/") + ".class", i.getClassData());
boolean auxiliaryApplication = curatedApplication.getQuarkusBootstrap().isAuxiliaryApplication();
builder.setAuxiliaryApplication(auxiliaryApplication);
builder.setAuxiliaryDevModeType(
curatedApplication.getQuarkusBootstrap().isHostApplicationIsTestOnly() ? DevModeType.TEST_ONLY
: (auxiliaryApplication ? DevModeType.LOCAL : null));
builder.setLaunchMode(LaunchMode.NORMAL);
builder.setRebuild(quarkusBootstrap.isRebuild());
builder.setLiveReloadState(
new LiveReloadBuildItem(false, Collections.emptySet(), new HashMap<>(), null));
for (AdditionalDependency i : quarkusBootstrap.getAdditionalApplicationArchives()) {
//this gets added to the class path either way
//but we only need to add it to the additional app archives
//if it is forced as an app archive
if (i.isForceApplicationArchive()) {
builder.addAdditionalApplicationArchive(i.getResolvedPaths());
}
}
builder.addBuildChainCustomizer(new Consumer<BuildChainBuilder>() {
@Override
public void accept(BuildChainBuilder builder) {
final BuildStepBuilder stepBuilder = builder.addBuildStep((ctx) -> {
ctx.produce(new ProcessInheritIODisabledBuildItem());
});
stepBuilder.produces(ProcessInheritIODisabledBuildItem.class).build();
}
});
builder.excludeFromIndexing(quarkusBootstrap.getExcludeFromClassPath());
builder.addFinal(GeneratedClassBuildItem.class);
builder.addFinal(MainClassBuildItem.class);
builder.addFinal(GeneratedResourceBuildItem.class);
builder.addFinal(TransformedClassesBuildItem.class);
builder.addFinal(DeploymentResultBuildItem.class);
// note: quarkus.package.type is deprecated
boolean nativeRequested = "native".equals(System.getProperty("quarkus.package.type"))
|| "true".equals(System.getProperty("quarkus.native.enabled"));
boolean containerBuildRequested = Boolean.getBoolean("quarkus.container-image.build");
if (nativeRequested) {
builder.addFinal(NativeImageBuildItem.class);
}
for (GeneratedResourceBuildItem i : buildResult.consumeMulti(GeneratedResourceBuildItem.class)) {
result.put(i.getName(), i.getData());
if (containerBuildRequested) {
//TODO: this is a bit ugly
//we don't necessarily need these artifacts
//but if we include them it does mean that you can auto create docker images
//and deploy to kube etc
//for an ordinary build with no native and no docker this is a waste
builder.addFinal(ArtifactResultBuildItem.class);
}
for (Map.Entry<Path, Set<TransformedClassesBuildItem.TransformedClass>> entry : buildResult
.consume(TransformedClassesBuildItem.class).getTransformedClassesByJar().entrySet()) {
for (TransformedClassesBuildItem.TransformedClass transformed : entry.getValue()) {
if (transformed.getData() != null) {
result.put(transformed.getFileName(), transformed.getData());
} else {
log.warn("Unable to remove resource " + transformed.getFileName()
+ " as this is not supported in JBangf");

try {
BuildResult buildResult = builder.build().run();
Map<String, byte[]> result = new HashMap<>();
for (GeneratedClassBuildItem i : buildResult.consumeMulti(GeneratedClassBuildItem.class)) {
result.put(i.getName().replace(".", "/") + ".class", i.getClassData());
}
for (GeneratedResourceBuildItem i : buildResult.consumeMulti(GeneratedResourceBuildItem.class)) {
result.put(i.getName(), i.getData());
}
for (Map.Entry<Path, Set<TransformedClassesBuildItem.TransformedClass>> entry : buildResult
.consume(TransformedClassesBuildItem.class).getTransformedClassesByJar().entrySet()) {
for (TransformedClassesBuildItem.TransformedClass transformed : entry.getValue()) {
if (transformed.getData() != null) {
result.put(transformed.getFileName(), transformed.getData());
} else {
log.warn("Unable to remove resource " + transformed.getFileName()
+ " as this is not supported in JBangf");
}
}
}
resultMap.put("files", result);
final List<String> javaargs = new ArrayList<>();
javaargs.add("-Djava.util.logging.manager=org.jboss.logmanager.LogManager");
javaargs.add(
"-Djava.util.concurrent.ForkJoinPool.common.threadFactory=io.quarkus.bootstrap.forkjoin.QuarkusForkJoinWorkerThreadFactory");
resultMap.put("java-args", javaargs);
resultMap.put("main-class", buildResult.consume(MainClassBuildItem.class).getClassName());
if (nativeRequested) {
resultMap.put("native-image", buildResult.consume(NativeImageBuildItem.class).getPath());
}
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
resultMap.put("files", result);
final List<String> javaargs = new ArrayList<>();
javaargs.add("-Djava.util.logging.manager=org.jboss.logmanager.LogManager");
javaargs.add(
"-Djava.util.concurrent.ForkJoinPool.common.threadFactory=io.quarkus.bootstrap.forkjoin.QuarkusForkJoinWorkerThreadFactory");
resultMap.put("java-args", javaargs);
resultMap.put("main-class", buildResult.consume(MainClassBuildItem.class).getClassName());
if (nativeRequested) {
resultMap.put("native-image", buildResult.consume(NativeImageBuildItem.class).getPath());
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Loading

0 comments on commit 1daa43b

Please sign in to comment.