-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
Describe the bug
During erroneous native image build using GraalVM 24 (both CE and Oracle) error message isn't displayed in the build output, or unrelated warning are printed. This leads to confusion. Meanwhile GraalVM 21 works fine and displays related output. The same is true with building using Docker builder image quay.io/quarkus/ubi-quarkus-mandrel-builder-image:jdk-24/quarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-graalvmce-builder-image:jdk-24.
Expected behavior
Build error message is displayed, or at least output is visible. download full output
> sdk use java 21.0.2-graal
> ./gradlew build
<... skipped noise 0. >
Error: Detected an instance of Random/SplittableRandom class in the image heap. Instances created during image generation have cached seed values and don't behave as expected. If these objects should not be stored in the image heap, you can use
'--trace-object-instantiation=java.security.SecureRandom'
to find classes that instantiate these objects. Once you found such a class, you can mark it explicitly for run time initialization with
'--initialize-at-run-time=<culprit>'
< skipped more error messages >
> Task :quarkusAppPartsBuild FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':quarkusAppPartsBuild'.
> There was a failure while executing work items
> A failure occurred while executing io.quarkus.gradle.tasks.worker.BuildWorker
> io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[error]: Build step io.quarkus.deployment.pkg.steps.NativeImageBuildStep#build threw an exception: io.quarkus.deployment.pkg.steps.NativeImageBuildStep$ImageGenerationFailureException: Image generation failed
<... stacktrace >
at org.jboss.threads.JBossThread.run(JBossThread.java:501)
Caused by: io.smallrye.common.process.AbnormalExitException: Process exited abnormally (pid 36798) with exit code 1 with error output:
> SLF4J: Class path contains multiple SLF4J providers.
> SLF4J: Found provider [org.slf4j.impl.JBossSlf4jServiceProvider@14daf3a6]
> SLF4J: Found provider [org.slf4j.simple.SimpleServiceProvider@5ba8c0ed]
> SLF4J: Found provider [org.slf4j.reload4j.Reload4jServiceProvider@6acdbcce]
> SLF4J: See https://www.slf4j.org/codes.html#multiple_bindings for an explanation.
> … (skipped 62 line(s)) …
>
>
> at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.constraints.UnsupportedFeatures.report(UnsupportedFeatures.java:126)
> at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:809)
> ... 6 more
<... stacktrace>
... 10 more
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
BUILD FAILED in 21s
❯
Actual behavior
Actual error message is not displayed, no output is present, download full output
# Same with 24.0.2-graalce
sdk use java 24.0.2-graal
❯ ./gradlew build
<... skipped noise, see full file attached 24_no_error_full.txt>
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':quarkusAppPartsBuild'.
> There was a failure while executing work items
> A failure occurred while executing io.quarkus.gradle.tasks.worker.BuildWorker
> io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[error]: Build step io.quarkus.deployment.pkg.steps.NativeImageBuildStep#build threw an exception: io.quarkus.deployment.pkg.steps.NativeImageBuildStep$ImageGenerationFailureException: Image generation failed
at < ... skipped stacktrace>
at java.base/java.lang.Thread.run(Thread.java:1447)
at org.jboss.threads.JBossThread.run(JBossThread.java:501)
Caused by: io.smallrye.common.process.AbnormalExitException: Process exited abnormally (pid 34996) with exit code 1 with error output:
> SLF4J: Class path contains multiple SLF4J providers.
> SLF4J: Found provider [org.slf4j.impl.JBossSlf4jServiceProvider@7ac5410b]
> SLF4J: Found provider [org.slf4j.simple.SimpleServiceProvider@11453cc0]
> SLF4J: Found provider [org.slf4j.reload4j.Reload4jServiceProvider@5115e73]
> SLF4J: See https://www.slf4j.org/codes.html#multiple_bindings for an explanation.
> SLF4J: Actual provider is of type [org.slf4j.impl.JBossSlf4jServiceProvider@7ac5410b]
at io.smallrye.common.process.PipelineRunner.collectProblems(PipelineRunner.java:560)
<... rest of stacktrace >
... 10 more
BUILD FAILED in 18s
11 actionable tasks: 3 executed, 8 up-to-date
How to Reproduce?
Assumed that you have sdkman installed, and 2 test JDKs are too: sdk install java 24.0.2-graal && sdk install java 21.0.2-graal
- Clone example repo:
git@github.com:klakpin/quarkus-native-diff-example.git && cd quarkus-native-diff-example
. This repo contains spilled SecureRandom instance that fails GraalVM build and duplicate log bindings so warning message will be displayed - Try to build it with Graal 21:
sdk use java 21.0.2-graal && ./gradlew build
- The error message is printed in task output. If you comment the multiple log dependencies in build.gradle.kts original correct error message will be displayed in stacktrace
- Try to build it with Graal 24:
sdk use java 24.0.2-graal && ./gradlew build
- The error message is not visible in task output. Moreover, confusing unrelated warnings are printed. If log dependencies are removed zero error information will be provided
- Cleanup: remove installed SDKs:
sdk uninstall java 24.0.2-graal && sdk uninstall java 21.0.2-graal
Docker container build flow:
- In example repo add additional properties to src/main/resources/application.properties:
# quarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-graalvmce-builder-image:jdk-24
quarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-mandrel-builder-image:jdk-24
quarkus.native.container-build=true
quarkus.container-image.build=true
quarkus.native.container-runtime=docker
- Try to build the project
/gradlew build
- No error message is displayed
Output of uname -a
or ver
24.5.0 Darwin Kernel Version 24.5.0: Tue Apr 22 19:54:29 PDT 2025; root:xnu-11417.121.6~2/RELEASE_ARM64_T6030 arm64
Output of java -version
java 24.0.2 2025-07-15
Mandrel or GraalVM version (if different from Java)
24.0.2-graal
Quarkus version or git rev
3.25.0
Build tool (ie. output of mvnw --version
or gradlew --version
)
Gradle 8.14
Additional information
Looks like GraalVM 24 prints build log differently. Specifically if we will run the native-image tool as Quarkus does download script ./run_native.build.sh
* we will see different behavior with stdout/stderr. In one case error is printed in the terminal directly and output is stored, in other one error also stored in output. I assume this is related to a specific handling of output and stderror during Native image task:
log.info(String.join(" ", buildCommand).replace("$", "\\$"));
ProcessBuilder.newBuilder(buildCommand[0])
.arguments(Arrays.copyOfRange(buildCommand, 1, buildCommand.length))
.directory(outputDir)
.whileRunning(ph -> {
if (!ph.isAlive()) {
return;
}
// todo: maybe have a "destroy-on-shutdown" switch?
Thread hook = new Thread(() -> {
if (ph.supportsNormalTermination()) {
// ask nicely (not supported on Windows)
ph.destroy();
}
ph.waitUninterruptiblyFor(10, TimeUnit.SECONDS);
ProcessUtil.destroyAllForcibly(ph);
}, "GraalVM terminator");
Runtime.getRuntime().addShutdownHook(hook);
try {
ph.waitUninterruptiblyFor();
} finally {
Runtime.getRuntime().removeShutdownHook(hook);
}
})
.output().consumeLinesWith(8192, log::info)
// Why logOnSuccess(false) and then consumeWith? Because we get the stdErr twice otherwise.
.error().logOnSuccess(false)
.consumeWith(br -> new ErrorReplacingProcessReader(br, outputDir.resolve("reports").toFile()).run())
.run();
But I didn't come up with ideas how to correctly fix it.
run_native.build.sh
script should be executed from build/quarkus-native-versions-diff-1.0-SNAPSHOT-native-image-source-jar directory with correct JDK