Skip to content

Conversation

Karm
Copy link
Member

@Karm Karm commented Jul 16, 2025

The problem is that io.smallrye.common.process treats non empty stdErr as something to print a WARNING about.
At best case it prints the stdErr twice. A worse scenario is a confusion caused for log scanning tools such as Mandrel integration testsuite that suddenly report benign things like:

[WARNING] [io.smallrye.common.process] SRCOM05000: Command podman (pid 2448670) completed but logged errors:
        Trying to pull quay.io/quarkus/ubi-quarkus-mandrel-builder-image:dev...
        Getting image source signatures

i.e. it makes a WARNING out of a perfectly fine podman output.

This PR scratches the itch for some cases, but the Quarkus codebase seems riddled wit Smallrye process now, so perhaps a more general solution would be in order.

@Karm
Copy link
Member Author

Karm commented Jul 16, 2025

@dmlloyd at the risk of asking a stupid question in public, I would like to know why we have Smallrye Process in Quarkus in the first place? It seems it doesn't wrap any Windows quirks JDK 17 Process API has anyway. Or does it...?
It feels as a cumbersome complication for such straightforward cases as running a single command we need to wait for anyway, e.g. cc, or native-image or podman etc. And the API looks very similar too, e.g. consuming stdOut/stdErr, handing over env vars etc.

If there are any benefits for more complex dev mode scenarios or something like that, why don't we use it only there?

@dmlloyd
Copy link
Member

dmlloyd commented Jul 16, 2025

The problem is that it is nearly impossible to properly handle I/O and threading correctly (as evidenced by many places which were incorrect, some of which already caused hangs and other issues).

The JDK API is deceptively simple, but there are many subtleties not accounted for.

@Karm
Copy link
Member Author

Karm commented Jul 16, 2025

@dmlloyd Thanks. I'm glad the dependency does something more then.

Do you think it would be justified to go to the Smallrye Process and refactor it so as it "doesn't do this with stdErr" or do we deal with it in Quarkus case by case?

@dmlloyd
Copy link
Member

dmlloyd commented Jul 16, 2025

It is working as designed; in most cases, the subprocess will output errors on the error stream, and thus the useful information is gathered into the exception or logged if an exception is not thrown. Processes which don't do this are the exception, not the rule.

Copy link

quarkus-bot bot commented Jul 17, 2025

Status for workflow Quarkus CI

This is the status report for running Quarkus CI on commit b07355f.

Failing Jobs

Status Name Step Failures Logs Raw logs Build scan
Native Tests - Windows support Build Failures Logs Raw logs 🔍

You can consult the Develocity build scans.

Failures

⚙️ Native Tests - Windows support #

- Failing: integration-tests/liquibase 

📦 integration-tests/liquibase

Failed to execute goal io.quarkus:quarkus-maven-plugin:999-SNAPSHOT:build (default) on project quarkus-integration-test-liquibase: Failed to build quarkus application


Flaky tests - Develocity

⚙️ JVM Tests - JDK 17

📦 extensions/resteasy-reactive/rest-client/deployment

io.quarkus.rest.client.reactive.stork.StorkResponseTimeLoadBalancerTest.shouldUseFasterService - History

  • expected: "hello, Alice" but was: "hello, I'm a slow server" - org.opentest4j.AssertionFailedError
org.opentest4j.AssertionFailedError: 

expected: "hello, Alice"
 but was: "hello, I'm a slow server"
	at io.quarkus.rest.client.reactive.stork.StorkResponseTimeLoadBalancerTest.shouldUseFasterService(StorkResponseTimeLoadBalancerTest.java:58)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at io.quarkus.test.QuarkusUnitTest.runExtensionMethod(QuarkusUnitTest.java:534)
	at io.quarkus.test.QuarkusUnitTest.interceptTestMethod(QuarkusUnitTest.java:448)

@Karm
Copy link
Member Author

Karm commented Jul 17, 2025

This Liquidbase failure actually seems serious: Error: An object of type 'java.lang.ProcessEnvironment' was found in the image heap

Would be weird if this PR is the cause, but I'll try to reproduce it locally nonetheless.

 Caused by: io.quarkus.deployment.pkg.steps.NativeImageBuildStep$ImageGenerationFailureException: Image generation failed
    at io.quarkus.deployment.pkg.steps.NativeImageBuildStep.imageGenerationFailed (NativeImageBuildStep.java:497)
    at io.quarkus.deployment.pkg.steps.NativeImageBuildStep.build (NativeImageBuildStep.java:288)
    at java.lang.invoke.MethodHandle.invokeWithArguments (MethodHandle.java:733)
    at io.quarkus.deployment.ExtensionLoader$3.execute (ExtensionLoader.java:873)
    at io.quarkus.builder.BuildContext.run (BuildContext.java:255)
    at org.jboss.threads.ContextHandler$1.runWith (ContextHandler.java:18)
    at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith (EnhancedQueueExecutor.java:2651)
    at org.jboss.threads.EnhancedQueueExecutor$Task.run (EnhancedQueueExecutor.java:2630)
    at org.jboss.threads.EnhancedQueueExecutor.runThreadBody (EnhancedQueueExecutor.java:1622)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run (EnhancedQueueExecutor.java:1589)
    at java.lang.Thread.run (Thread.java:1583)
    at org.jboss.threads.JBossThread.run (JBossThread.java:501)
Caused by: io.smallrye.common.process.AbnormalExitException: Process exited abnormally (pid 3396) with exit code 1 with error output:
 > Error: An object of type 'java.lang.ProcessEnvironment' was found in the image heap. This type, however, is marked for initialization at image run time for the following reason: classes are initialized at run time by default.
 > This is not allowed for correctness reasons: All objects that are stored in the image heap must be initialized at build time.
 > 

@geoand
Copy link
Contributor

geoand commented Jul 17, 2025

The problem is that it is nearly impossible to properly handle I/O and threading correctly (as evidenced by many places which were incorrect, some of which already caused hangs and other issues).

The JDK API is deceptively simple, but there are many subtleties not accounted for.

And the Javadoc of io.smallrye.common.process.ProcessBuilder mentions these issues in detail

@geoand
Copy link
Contributor

geoand commented Jul 17, 2025

This Liquidbase failure actually seems serious: Error: An object of type 'java.lang.ProcessEnvironment' was found in the image heap

Would be weird if this PR is the cause, but I'll try to reproduce it locally nonetheless.

 Caused by: io.quarkus.deployment.pkg.steps.NativeImageBuildStep$ImageGenerationFailureException: Image generation failed
    at io.quarkus.deployment.pkg.steps.NativeImageBuildStep.imageGenerationFailed (NativeImageBuildStep.java:497)
    at io.quarkus.deployment.pkg.steps.NativeImageBuildStep.build (NativeImageBuildStep.java:288)
    at java.lang.invoke.MethodHandle.invokeWithArguments (MethodHandle.java:733)
    at io.quarkus.deployment.ExtensionLoader$3.execute (ExtensionLoader.java:873)
    at io.quarkus.builder.BuildContext.run (BuildContext.java:255)
    at org.jboss.threads.ContextHandler$1.runWith (ContextHandler.java:18)
    at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith (EnhancedQueueExecutor.java:2651)
    at org.jboss.threads.EnhancedQueueExecutor$Task.run (EnhancedQueueExecutor.java:2630)
    at org.jboss.threads.EnhancedQueueExecutor.runThreadBody (EnhancedQueueExecutor.java:1622)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run (EnhancedQueueExecutor.java:1589)
    at java.lang.Thread.run (Thread.java:1583)
    at org.jboss.threads.JBossThread.run (JBossThread.java:501)
Caused by: io.smallrye.common.process.AbnormalExitException: Process exited abnormally (pid 3396) with exit code 1 with error output:
 > Error: An object of type 'java.lang.ProcessEnvironment' was found in the image heap. This type, however, is marked for initialization at image run time for the following reason: classes are initialized at run time by default.
 > This is not allowed for correctness reasons: All objects that are stored in the image heap must be initialized at build time.
 > 

Yes, I have an open PR that hopefully fixes this

@geoand geoand merged commit 807bfbc into quarkusio:main Jul 17, 2025
56 of 57 checks passed
@quarkus-bot quarkus-bot bot added this to the 3.26 - main milestone Jul 17, 2025
@Eng-Fouad
Copy link
Contributor

This Liquidbase failure actually seems serious: Error: An object of type 'java.lang.ProcessEnvironment' was found in the image heap

Would be weird if this PR is the cause, but I'll try to reproduce it locally nonetheless.

 Caused by: io.quarkus.deployment.pkg.steps.NativeImageBuildStep$ImageGenerationFailureException: Image generation failed
    at io.quarkus.deployment.pkg.steps.NativeImageBuildStep.imageGenerationFailed (NativeImageBuildStep.java:497)
    at io.quarkus.deployment.pkg.steps.NativeImageBuildStep.build (NativeImageBuildStep.java:288)
    at java.lang.invoke.MethodHandle.invokeWithArguments (MethodHandle.java:733)
    at io.quarkus.deployment.ExtensionLoader$3.execute (ExtensionLoader.java:873)
    at io.quarkus.builder.BuildContext.run (BuildContext.java:255)
    at org.jboss.threads.ContextHandler$1.runWith (ContextHandler.java:18)
    at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith (EnhancedQueueExecutor.java:2651)
    at org.jboss.threads.EnhancedQueueExecutor$Task.run (EnhancedQueueExecutor.java:2630)
    at org.jboss.threads.EnhancedQueueExecutor.runThreadBody (EnhancedQueueExecutor.java:1622)
    at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run (EnhancedQueueExecutor.java:1589)
    at java.lang.Thread.run (Thread.java:1583)
    at org.jboss.threads.JBossThread.run (JBossThread.java:501)
Caused by: io.smallrye.common.process.AbnormalExitException: Process exited abnormally (pid 3396) with exit code 1 with error output:
 > Error: An object of type 'java.lang.ProcessEnvironment' was found in the image heap. This type, however, is marked for initialization at image run time for the following reason: classes are initialized at run time by default.
 > This is not allowed for correctness reasons: All objects that are stored in the image heap must be initialized at build time.
 > 

Got the same error here: #48598

@geoand
Copy link
Contributor

geoand commented Jul 17, 2025

#48954 will hopefully fix that

@Karm
Copy link
Member Author

Karm commented Jul 20, 2025

😃 I did not realize I am talking to the very father of the initiative [1] here, DML.

Running test suites on various platforms over the years, we accumulated a collection of hacks, traversing and killing all child processes first, remembering PID and calling Windows wmic and task kill in cmd rather than relying on Java API, having a tiny C executable that attaches to a detached terminal process and sends it CtrlC, to be able to gracefully stop Quarkus in some Windows environments etc., properly consuming, forwarding or getting rid off streams... I'll have a look if anything could be worth generalizing and contributing to SmallRye.

[1] #48223

@gsmet
Copy link
Member

gsmet commented Aug 11, 2025

This should have been backported, marking for backport.

@gsmet gsmet modified the milestones: 3.26 - main, 3.25.3 Aug 12, 2025
@Sanne
Copy link
Member

Sanne commented Aug 14, 2025

This should have been backported, marking for backport.

yes please

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Native image: testGCCArgument produces confusing warnings

6 participants