quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.86k stars 2.71k forks source link

Gradle plugin: output Docker logs when doing buildNative/testNative #7549

Closed rbraeunlich closed 4 years ago

rbraeunlich commented 4 years ago

Description When building of my Quarkus native image with Gradle fail I have no chance to see the actual error output from the Docker image. ./gradlew testNative e.g. only fails with

Caused by: java.lang.RuntimeException: Image generation failed. Exit code: 1.

In that case everything has to be repeated and I manually have to do docker logs -f on the build image to see what's actually wrong. Appending --stacktrace or --debug didn't help. It would be great to directly see what went wrong and not have to wait for the native build twice.

Implementation ideas I'm not sure, but since the Gradle plugin is capable of starting a Docker image it might also be possible to attach to the logging of that container.

quarkusbot commented 4 years ago

/cc @quarkusio/devtools

lfmunoz commented 4 years ago

I have the same problem when I do ./gradlew buildNative it doesn't show why it is failing the build. Even with --debug and --stacktrace. You basically get a useless generic error that the build failed.

Failed to generate a native image
> Failed to augment application classes
  > Build failure: Build failed due to errors
        [error]: Build step io.quarkus.deployment.pkg.steps.NativeImageBuildStep#build threw an exception: java.lang.RuntimeException: Failed to build native image
        at io.quarkus.deployment.pkg.steps.NativeImageBuildStep.build(NativeImageBuildStep.java:319)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at io.quarkus.deployment.ExtensionLoader$2.execute(ExtensionLoader.java:915)
        at io.quarkus.builder.BuildContext.run(BuildContext.java:279)
        at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
        at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2011)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1535)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1426)
        at java.lang.Thread.run(Thread.java:748)
        at org.jboss.threads.JBossThread.run(JBossThread.java:479)
    Caused by: java.lang.RuntimeException: Image generation failed. Exit code: 1
        at io.quarkus.deployment.pkg.steps.NativeImageBuildStep.build(NativeImageBuildStep.java:308)
        ... 12 more

    > Failed to build native image
      > Image generation failed. Exit code: 1

A workaround is to do ./gradlew buildNative --docker-build=true and then inspect what the docker image is doing to build and see what errors are happening there.

jmarshall5-chwy commented 4 years ago

Just thought I would add to this I had a @ConfigProperties class which has the following

`java @ConfigProperties(prefix = "vs", namingStrategy = ConfigProperties.NamingStrategy.VERBATIM) public class ConfigServerProp {

@ConfigProperty(name =  "engineMaxAddresses", defaultValue = "100")
private Integer engineMaxAddresses;

public int getEngineMaxAddresses() {
    return engineMaxAddresses < 1 ? 1 : engineMaxAddresses;
}

public void setEngineMaxAddresses(Integer engineMaxAddresses) {
    this.engineMaxAddresses = engineMaxAddresses;
}

`

I was getting the error java.lang.RuntimeException: Image generation failed. Exit code: 1 because of the return type of the getEngineMaxAddresses function was returning the raw type while the set function took the object type. Changing the get function to return an Integer class solved the issue.

The way I determined this was by running the gradlew build with docker

./gradlew buildNative -i --stacktrace --docker-build=true -Dquarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-native-image:19.3.1-java11

Then finding the container being used by docker and running

docker logs -f [container_name]

Hopefully this may help someone else.

marc-christian-schulze commented 4 years ago

I'm experiencing the same issue. The buildNative task of the Gradle plugin does not print any of the stdout or stderr logs of the native-image command - regardless whether run inside of a Docker container or natively on the host. Looking into the Quarkus sources the ProcessBuilder that is used inherits the i/o streams from the parent process - which is Gradle. It seems that Gradle did replace its own stdout and stderr stream since log data is not passed on to the calling console / terminal which seems different in Maven. I assume Quarkus needs to log directly using the Gradle logging system instead of relying on stdout and stderr.

maxandersen commented 4 years ago

fwiw it looks like gradle have deficiency here and don't provide. a good api to handle stdout/stderr redirection/piping. https://github.com/gradle/gradle/issues/6068

I guess we could put a custom redirection in place but that just sounds wrong...

dforsl commented 4 years ago

+1 on this.

Fixing this would be so appreciated... It's a really frustrating dev-experience when native-image is failing and you can't see why.

jaikiran commented 4 years ago

Hello @marc-christian-schulze and others, the missing logs from native image generation during Gradle build should now be fixed with https://github.com/quarkusio/quarkus/pull/10137 merged into master branch of Quarkus.

Given that this issue here is mostly about these missing logs, I will close this as fixed (in next release). Please either reopen or create a new issue if you still run into this problem in the 1.6.x (upcoming) release.