paketo-buildpacks / oracle

A Cloud Native Buildpack that provides the Oracle JDK implementations of JREs and JDKs
Apache License 2.0
1 stars 3 forks source link

Builds fail with "native-image-svm/bin/native-image: no such file or directory" on macOS. #245

Closed fniephaus closed 3 months ago

fniephaus commented 3 months ago

Expected Behavior

Building a starter Spring Boot app via ./mvnw -Pnative spring-boot:build-image succeeds.

Current Behavior

Building a starter app fails with:

"native-image-svm/bin/native-image: no such file or directory" (expand for log) ``` [INFO] [creator] Using Java version 21 extracted from MANIFEST.MF [INFO] [creator] Oracle GraalVM 21.0.4: Contributing to layer [INFO] [creator] Downloading from https://download.oracle.com/graalvm/21/archive/graalvm-jdk-21.0.4_linux-aarch64_bin.tar.gz [INFO] [creator] Verifying checksum [INFO] [creator] Expanding to /layers/paketo-buildpacks_oracle/native-image-svm [INFO] [creator] Adding 137 container CA certificates to JVM truststore [INFO] [creator] Writing env.build/JAVA_HOME.override [INFO] [creator] Writing env.build/JDK_HOME.override [INFO] [creator] [INFO] [creator] Paketo Buildpack for CA Certificates 3.8.4 [INFO] [creator] https://github.com/paketo-buildpacks/ca-certificates [INFO] [creator] Build Configuration: [INFO] [creator] $BP_EMBED_CERTS false Embed certificates into the image [INFO] [creator] $BP_ENABLE_RUNTIME_CERT_BINDING true Deprecated: Enable/disable certificate helper layer to add certs at runtime [INFO] [creator] $BP_RUNTIME_CERT_BINDING_DISABLED false Disable certificate helper layer to add certs at runtime [INFO] [creator] Launch Helper: Contributing to layer [INFO] [creator] Creating /layers/paketo-buildpacks_ca-certificates/helper/exec.d/ca-certificates-helper [INFO] [creator] [INFO] [creator] Paketo Buildpack for Syft 1.47.2 [INFO] [creator] https://github.com/paketo-buildpacks/syft [INFO] [creator] Downloading from https://github.com/anchore/syft/releases/download/v0.105.1/syft_0.105.1_linux_amd64.tar.gz [INFO] [creator] Verifying checksum [INFO] [creator] Writing env.build/SYFT_CHECK_FOR_APP_UPDATE.default [INFO] [creator] [INFO] [creator] Paketo Buildpack for Executable JAR 6.11.0 [INFO] [creator] https://github.com/paketo-buildpacks/executable-jar [INFO] [creator] Command "packages" is deprecated, use `syft scan` instead [INFO] [creator] Class Path: Contributing to layer [INFO] [creator] Writing env/CLASSPATH.delim [INFO] [creator] Writing env/CLASSPATH.prepend [INFO] [creator] Process types: [INFO] [creator] executable-jar: java org.springframework.boot.loader.launch.JarLauncher (direct) [INFO] [creator] task: java org.springframework.boot.loader.launch.JarLauncher (direct) [INFO] [creator] web: java org.springframework.boot.loader.launch.JarLauncher (direct) [INFO] [creator] [INFO] [creator] Paketo Buildpack for Spring Boot 5.31.0 [INFO] [creator] https://github.com/paketo-buildpacks/spring-boot [INFO] [creator] Build Configuration: [INFO] [creator] $BPL_JVM_CDS_ENABLED false whether to enable CDS optimizations at runtime [INFO] [creator] $BPL_SPRING_AOT_ENABLED false whether to enable Spring AOT at runtime [INFO] [creator] $BP_JVM_CDS_ENABLED false whether to enable CDS & perform JVM training run [INFO] [creator] $BP_SPRING_AOT_ENABLED false whether to enable Spring AOT [INFO] [creator] $BP_SPRING_CLOUD_BINDINGS_DISABLED false whether to contribute Spring Boot cloud bindings support [INFO] [creator] $BP_SPRING_CLOUD_BINDINGS_VERSION 1 default version of Spring Cloud Bindings library to contribute [INFO] [creator] Launch Configuration: [INFO] [creator] $BPL_SPRING_CLOUD_BINDINGS_DISABLED false whether to auto-configure Spring Boot environment properties from bindings [INFO] [creator] $BPL_SPRING_CLOUD_BINDINGS_ENABLED true Deprecated - whether to auto-configure Spring Boot environment properties from bindings [INFO] [creator] Class Path: Contributing to layer [INFO] [creator] Writing env.build/CLASSPATH.append [INFO] [creator] Writing env.build/CLASSPATH.delim [INFO] [creator] Image labels: [INFO] [creator] org.opencontainers.image.title [INFO] [creator] org.opencontainers.image.version [INFO] [creator] org.springframework.boot.version [INFO] [creator] [INFO] [creator] Paketo Buildpack for Native Image 5.14.2 [INFO] [creator] https://github.com/paketo-buildpacks/native-image [INFO] [creator] Build Configuration: [INFO] [creator] $BP_BINARY_COMPRESSION_METHOD Compression mechanism used to reduce binary size. Options: `none` (default), `upx` or `gzexe` [INFO] [creator] $BP_NATIVE_IMAGE true enable native image build [INFO] [creator] $BP_NATIVE_IMAGE_BUILD_ARGUMENTS arguments to pass to the native-image command [INFO] [creator] $BP_NATIVE_IMAGE_BUILD_ARGUMENTS_FILE a file with arguments to pass to the native-image command [INFO] [creator] $BP_NATIVE_IMAGE_BUILT_ARTIFACT the built application artifact explicitly, required if building from a JAR [INFO] [creator] Command "packages" is deprecated, use `syft scan` instead [INFO] [creator] unable to invoke layer creator [INFO] [creator] error running version [INFO] [creator] unable to start PTY [INFO] [creator] fork/exec /layers/paketo-buildpacks_oracle/native-image-svm/bin/native-image: no such file or directory [INFO] [creator] ERROR: failed to build: exit status 1 [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 03:58 min [INFO] Finished at: 2024-07-31T12:09:16+03:00 [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:3.3.2:build-image (default-cli) on project demo: Execution default-cli of goal org.springframework.boot:spring-boot-maven-plugin:3.3.2:build-image failed: Builder lifecycle 'creator' failed with status code 51 -> [Help 1] ```

Possible Solution

I have no idea what is causing this issue. According to the log, the right GraalVM distribution is downloaded and extracted. It also contains a bin/native-image. However, somehow it is not found by the buildpack infrastructure. Note that this works fine on Linux, and with the default buildpack on macOS.

Steps to Reproduce

  1. Use a macOS machine.
  2. Download a starter app from https://start.spring.io/
  3. Add the following right below <artifactId>spring-boot-maven-plugin</artifactId> in the pom.xml:
  <configuration>
    <image>
      <buildpacks>
        <buildpack>docker.io/paketobuildpacks/oracle</buildpack>
        <buildpack>urn:cnb:builder:paketo-buildpacks/java-native-image</buildpack>
      </buildpacks>
    </image>
  </configuration>
  1. Run ./mvnw -Pnative spring-boot:build-image

Motivations

macOS users are potentially unable to build with Oracle GraalVM using buildpacks.

cc @olyagpl

dmikusa commented 3 months ago

@fniephaus @olyagpl -> have you tried with the sample app? https://github.com/paketo-buildpacks/samples/tree/main/java/native-image/spring-boot-native-image-maven

Does that work for you?

I would also suggest that you put in:

        <configuration>
          <image>
            <builder>paketobuildpacks/builder-jammy-buildpackless-tiny</builder>
            <buildpacks>
                <buildpack>docker.io/paketobuildpacks/oracle</buildpack>
                <buildpack>docker.io/paketo-buildpacks/java-native-image</buildpack>
            </buildpacks>
          </image>
        </configuration>

Right now the only builder that has ARM64 support is this one, builder-jammy-buildpackless-tiny. If you don't set that builder then it'll default to the builder-jammy-base builder which is not ARM64 compatible. That might cause some weirdness, although it's interesting cause from your logs it is installing an aarch64 GraalVM distribution.

olyagpl commented 3 months ago

@dmikusa, sample app is fine if you run with the existing configuration (it pulls bellsoft-liberica-vm-openjdk22.0.1+10-24.0.1+1-linux-aarch64.tar.gz). Once I switch the buildpack, it fails with urn:cnb:builder:paketo-buildpacks/java-native-image not found in builder.

[INFO] Building image 'docker.io/library/demo:0.0.1-SNAPSHOT'
[INFO] 
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder-jammy-buildpackless-tiny:latest' 100%
[INFO]  > Pulled builder image 'paketobuildpacks/builder-jammy-buildpackless-tiny@sha256:f3e428cbe70e7e32930eb1bfbe837f09a521039e5f2a25a5bd85d6ff95e10122'
[INFO]  > Pulling run image 'docker.io/paketobuildpacks/run-jammy-tiny:latest' 100%
[INFO]  > Pulled run image 'paketobuildpacks/run-jammy-tiny@sha256:0db51d00786437d728ec5d17ffdb8c0149be4ba29ade4e844b747db8494a71b9'
[INFO]  > Pulling buildpack image 'docker.io/paketobuildpacks/oracle:latest' 100%
[INFO]  > Pulled buildpack image 'paketobuildpacks/oracle@sha256:24e6089623150841db0347b4fd6565c9cdbd1215bb40819671fea1da04bfce0a'
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  33.352 s
[INFO] Finished at: 2024-08-12T17:16:10+03:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:3.3.2:build-image (default-cli) on project demo: Execution default-cli of goal org.springframework.boot:spring-boot-maven-plugin:3.3.2:build-image failed: Buildpack 'urn:cnb:builder:paketo-buildpacks/java-native-image' not found in builder -> [Help 1]
fniephaus commented 3 months ago

@dmikusa could you take another look at this please? What I don't understand is why the sample app with liberica works just fine on macOS, without even requesting paketobuildpacks/builder-jammy-buildpackless-tiny explicitly.

dmikusa commented 3 months ago

[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:3.3.2:build-image (default-cli) on project demo: Execution default-cli of goal org.springframework.boot:spring-boot-maven-plugin:3.3.2:build-image failed: Buildpack 'urn:cnb:builder:paketo-buildpacks/java-native-image' not found in builder -> [Help 1]

@olyagpl Sorry, 🤦 that's my fault. I needed to update reference from in the builder to point it to a docker image. This should work for you, or at least get you past this error.

        <configuration>
          <image>
            <builder>paketobuildpacks/builder-jammy-buildpackless-tiny</builder>
            <buildpacks>
                <buildpack>docker.io/paketobuildpacks/oracle</buildpack>
                <buildpack>docker.io/paketo-buildpacks/java-native-image</buildpack>
            </buildpacks>
          </image>
        </configuration>
dmikusa commented 3 months ago

could you take another look at this please? What I don't understand is why the sample app with liberica works just fine on macOS, without even requesting paketobuildpacks/builder-jammy-buildpackless-tiny explicitly.

@fniephaus That's a good question and I'm not totally sure off the top of my head. What's further confusing about it is that all of the JVM vendor buildpacks run the same code, from libjvm, so the difference between the code running is very small.

It possibly points to a configuration bug, but I did look through the configuration and nothing jumps out at me.

I'm also curious if the same thing happens when you run with pack cli, since it's a different buildpacks platform implementation. This would also build everything in the container, both Java and Native Image binary, where the Spring Boot Tools only build the native image binary in the container. Anyway, running a few more tests should help to narrow down what is causing the problem.

pack build applications/native-image \
  --builder paketobuildpacks/builder-jammy-buildpackless-tiny \
  --buildpack docker.io/paketobuildpacks/oracle \
  --buildpack docker.io/paketo-buildpacks/java-native-image \
  --env BP_MAVEN_ACTIVE_PROFILES=native
olyagpl commented 3 months ago

@dmikusa, updating the builder to point to a docker image leads to an invalid buildpack reference:

[INFO] 
[INFO] <<< spring-boot:3.3.2:build-image (default-cli) < package @ demo <<<
[INFO] 
[INFO] 
[INFO] --- spring-boot:3.3.2:build-image (default-cli) @ demo ---
[INFO] Building image 'docker.io/library/demo:0.0.1-SNAPSHOT'
[INFO] 
[INFO]  > Pulling builder image 'docker.io/paketobuildpacks/builder-jammy-buildpackless-tiny:latest' 100%
[INFO]  > Pulled builder image 'paketobuildpacks/builder-jammy-buildpackless-tiny@sha256:f3e428cbe70e7e32930eb1bfbe837f09a521039e5f2a25a5bd85d6ff95e10122'
[INFO]  > Pulling run image 'docker.io/paketobuildpacks/run-jammy-tiny:latest' 100%
[INFO]  > Pulled run image 'paketobuildpacks/run-jammy-tiny@sha256:0db51d00786437d728ec5d17ffdb8c0149be4ba29ade4e844b747db8494a71b9'
[INFO]  > Pulling buildpack image 'docker.io/paketobuildpacks/oracle:latest' 100%
[INFO]  > Pulled buildpack image 'paketobuildpacks/oracle@sha256:24e6089623150841db0347b4fd6565c9cdbd1215bb40819671fea1da04bfce0a'
[INFO]  > Pulling buildpack image 'docker.io/paketo-buildpacks/java-native-image:latest' 100%
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  44.321 s
[INFO] Finished at: 2024-08-15T16:43:28+03:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:3.3.2:build-image (default-cli) on project demo: Execution default-cli of goal org.springframework.boot:spring-boot-maven-plugin:3.3.2:build-image failed: Invalid buildpack reference 'docker.io/paketo-buildpacks/java-native-image' -> [Help 1]
dmikusa commented 3 months ago

I was able to run the sample app just fine by adding in the Oracle buildpack.

    <build>
        <plugins>
            <plugin>
                <groupId>org.graalvm.buildtools</groupId>
                <artifactId>native-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <image>
            <builder>paketobuildpacks/builder-jammy-buildpackless-tiny</builder>
            <buildpacks>
              <buildpack>paketobuildpacks/oracle</buildpack>
              <buildpack>paketobuildpacks/java-native-image</buildpack>
            </buildpacks>
          </image>
        </configuration>
            </plugin>
        </plugins>
    </build>

All I added was <buildpack>paketobuildpacks/oracle</buildpack>.

The build looks OK to me.

[INFO]     [creator]       Oracle GraalVM 21.0.4: Contributing to layer
[INFO]     [creator]         Downloading from https://download.oracle.com/graalvm/21/archive/graalvm-jdk-21.0.4_linux-aarch64_bin.tar.gz
[INFO]     [creator]         Verifying checksum
[INFO]     [creator]         Expanding to /layers/paketo-buildpacks_oracle/native-image-svm
[INFO]     [creator]         Adding 137 container CA certificates to JVM truststore
[INFO]     [creator]         Writing env.build/JAVA_HOME.override
[INFO]     [creator]         Writing env.build/JDK_HOME.override

and ...

[INFO]     [creator]       Native Image: Contributing to layer
[INFO]     [creator]         Executing native-image --no-fallback -H:+StaticExecutableWithDynamicLibC @/workspace/META-INF/native-image/argfile -H:Name=/layers/paketo-buildpacks_native-image ...
...
[INFO]     [creator]     --------------------------------------------------------------------------------
[INFO]     [creator]     Produced artifacts:
[INFO]     [creator]      /layers/paketo-buildpacks_native-image/native-image/io.paketo.demo.DemoApplication (executable)
[INFO]     [creator]     ================================================================================
[INFO]     [creator]     Finished generating 'io.paketo.demo.DemoApplication' in 2m 7s.
[INFO]     [creator]       Removing bytecode
[INFO]     [creator]       Process types:
[INFO]     [creator]         native-image: ./io.paketo.demo.DemoApplication (direct)
[INFO]     [creator]         task:         ./io.paketo.demo.DemoApplication (direct)
[INFO]     [creator]         web:          ./io.paketo.demo.DemoApplication (direct)

and it runs OK too.

> docker run -it demo:0.0.1-SNAPSHOT

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v3.3.2)

2024-08-19T02:27:59.842Z  INFO 1 --- [           main] io.paketo.demo.DemoApplication           : Starting AOT-processed DemoApplication using Java 21.0.4 with PID 1 (/workspace/io.paketo.demo.DemoApplication started by cnb in /workspace)
2024-08-19T02:27:59.842Z  INFO 1 --- [           main] io.paketo.demo.DemoApplication           : No active profile set, falling back to 1 default profile: "default"
2024-08-19T02:27:59.866Z  INFO 1 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 14 endpoints beneath base path '/actuator'
2024-08-19T02:27:59.875Z  INFO 1 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port 8080 (http)
2024-08-19T02:27:59.876Z  INFO 1 --- [           main] io.paketo.demo.DemoApplication           : Started DemoApplication in 0.041 seconds (process running for 0.048)

That's on an MBP with an M1 processor, it was doing native ARM64 builds.

I ran it with pack build too and it works the same, pack build apps/native -B paketobuildpacks/builder-jammy-buildpackless-tiny -b paketo-buildpacks/oracle -b paketo-buildpacks/java-native-image -e BP_MAVEN_ACTIVE_PROFILES=native.

I pulled down a fresh app from start.spring.io and added in the configuration above, also working.

Can you give that a try and see how it goes? Thanks

olyagpl commented 3 months ago

@dmikusa, if using your suggested configuration, a native image is successfully built on Oracle GraalVM, and macOS ARM64. The differences from the original are:

  1. specify a builder explicitly to point it to a Docker image.
  2. update the buildpack paths removing docker.io at the beginning (from docker.io/paketo-buildpacks/java-native-image to paketo-buildpacks/java-native-image).

Thanks for helping out. We can close this case.

dmikusa commented 3 months ago

Thanks for trying and confirming. 2.) shouldn't matter. The tooling supports a couple of different ways of addressing a buildpack, they all end up pulling the same image. 1.) is probably the issue (although I can't 100% explain why).

We did just recently update all the samples to use the specific builder, so I hope that will help others get things working without as much hassle. Thanks for working through this one with me.