spring-projects / spring-boot

Spring Boot helps you to create Spring-powered, production-grade applications and services with absolute minimum fuss.
https://spring.io/projects/spring-boot
Apache License 2.0
75.09k stars 40.67k forks source link

Docker with Native Image not being applied when GPO is enabled #39581

Closed rodrigorodrigues closed 8 months ago

rodrigorodrigues commented 8 months ago

Hi I'm trying to optimised a native image following Alina's repo and seems the docker maven plugin is not working with GPO, at least I couldn't find the logs.

mvn -Pnative spring-boot:build-image

[INFO]     [creator]     ================================================================================
[INFO]     [creator]     GraalVM Native Image: Generating 'com.example.rinha.RinhaApplication' (static executable)...
[INFO]     [creator]     ================================================================================
[INFO]     [creator]     For detailed information and explanations on the build output, visit:
[INFO]     [creator]     https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/BuildOutput.md
[INFO]     [creator]     --------------------------------------------------------------------------------
[INFO]     [creator]     [1/8] Initializing...                                            (4.7s @ 0.17GB)
[INFO]     [creator]      Java version: 21.0.2+14-LTS, vendor version: Liberica-NIK-23.1.2-1
[INFO]     [creator]      Graal compiler: optimization level: 2, target machine: armv8-a
[INFO]     [creator]      C compiler: gcc (linux, aarch64, 11.4.0)
[INFO]     [creator]      Garbage collector: Serial GC (max heap size: 80% of RAM)
[INFO]     [creator]      2 user-specific feature(s):
[INFO]     [creator]      - com.oracle.svm.thirdparty.gson.GsonFeature
[INFO]     [creator]      - org.springframework.aot.nativex.feature.PreComputeFieldFeature
[INFO]     [creator]     --------------------------------------------------------------------------------

Using mvn -Pnative native:compile the extra configuration is picked fine.

========================================================================================================================
GraalVM Native Image: Generating 'app' (executable)...
========================================================================================================================
[1/8] Initializing...                                                                                    (9.8s @ 0.18GB)
 Java version: 21.0.2+13-LTS, vendor version: Oracle GraalVM 21.0.2+13.1
 Graal compiler: optimization level: 3, target machine: x86-64-v3, PGO: user-provided
 C compiler: gcc (linux, x86_64, 9.4.0)
 Garbage collector: G1 GC (max heap size: 25.0% of RAM)
 2 user-specific feature(s):
 - com.oracle.svm.thirdparty.gson.GsonFeature
 - org.springframework.aot.nativex.feature.PreComputeFieldFeature
------------------------------------------------------------------------------------------------------------------------

pom.xml

            <plugin>
                <groupId>org.graalvm.buildtools</groupId>
                <artifactId>native-maven-plugin</artifactId>
                <configuration>
                    <buildArgs>
                        <buildArg>--pgo=default.iprof</buildArg>
                        <buildArg>--gc=G1</buildArg>
                    </buildArgs>
                </configuration>
            </plugin>
philwebb commented 8 months ago

Unfortunately our buildpack integration doesn't yet support PGO. It looks like https://github.com/paketo-buildpacks/native-image has got a BP_NATIVE_IMAGE_BUILD_ARGUMENTS variable that we might be able to use, but we currently don't have a way to transfer the iprof file to the builder.

scottfrederick commented 8 months ago

The Spring Boot documentation shows two ways to build a native executable with GraalVM: 1) locally using Native Build Tools and 2) using Paketo buildpacks.

When using buildpacks with mvn -Pnative spring-boot:build-image, the configuration of the native-maven-plugin has no effect, since the Native Build Tools are being run inside a buildpack instead of being run by Maven. Instead you need to set the build arguments as an environment variable passed to the buildpacks, as Phil said above.

we currently don't have a way to transfer the iprof file to the builder.

It might be possible to do this with a binding, by configuring a binding and then giving the location of the binding in the NBT arguments like this:

        <plugin>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-maven-plugin</artifactId>
          <configuration>
            <image>
              <env>
                <BP_NATIVE_IMAGE_BUILD_ARGUMENTS>--pgo=/platform/bindings/default.iprof</BP_NATIVE_IMAGE_BUILD_ARGUMENTS>
              </env>
              <bindings>
                <binding>${basedir}/default.iprof:/platform/bindings/default.iprof</binding>
              </bindings>
            </image>
          </configuration>
        </plugin>

I'm not certain this would work without trying it. If it doesn't work, we could request that the Paketo native-image buidpack explicitly look for a binding to enable this in the same way that the Maven buildpack supports a binding that provides a settings.xml.

scottfrederick commented 8 months ago

Unfortunately, GraalVM PGO is not compatible with building docker images using buildpacks at this time.

The GraalVM documentation says:

Note: PGO is not available in GraalVM Community Edition.

The Paketo buildpacks that Spring Boot uses by default provide a buildpack for GraalVM Community Edition, but not for Oracle GraalVM. Until PGO is available in Community Edition, or there is a buildpack for Oracle GraalVM, PGO will not work with buildpacks. I'll close this issue as there's nothing Spring Boot can do to improve this situation.

rodrigorodrigues commented 8 months ago

Hi @scottfrederick yes, you're right tried that and didn't work.

ockExperimentalVMOptions' in the future.
[INFO]     [creator]     Warning: Please re-evaluate whether any experimental option is required, and either remove or unlock it. The build output lists all active experimental options, including where they come from and possible alternatives. If you think an experimental option should be considered as stable, please file an issue.
[INFO]     [creator]     Error: Unrecognized option(s): '--pgo=/platform/bindings/default.iprof'
[INFO]     [creator]     unable to invoke layer creator
[INFO]     [creator]     unable to contribute native-image layer
[INFO]     [creator]     error running build
[INFO]     [creator]     exit status 20
[INFO]     [creator]     ERROR: failed to build: exit status 1