Closed dmikusa closed 11 months ago
If you want to try this, I have a demo image available at docker.io/dmikusa/paketo-buildpacks-oracle
.
Ex:
pack build apps/native -p target/demo-0.0.1-SNAPSHOT.jar -e BP_NATIVE_IMAGE=true -e BP_JVM_VERSION=17 -b docker.io/dmikusa/paketo-buildpacks-oracle -b urn:cnb:builder:paketo-buildpacks/java-native-image -B paketobuildpacks/builder-jammy-tiny:latest
First of all, thanks a lot for putting this PR together, @dmikusa! I'll go over it next week and probably come back with a couple of questions. I just tried to see whether I can use this to build a simple Spring app, but unfortunately, the build fails with the following error:
[INFO] [creator] ======== Error: paketo-buildpacks/oracle@v3.9.4-10-gbd38a6c ========
[INFO] [creator] fork/exec /cnb/buildpacks/paketo-buildpacks_oracle/v3.9.4-10-gbd38a6c/bin/detect: exec format error
Not sure if this is me doing something wrong or a problem in your version of the oracle
buildpack?
Not sure if this is me doing something wrong or a problem in your version of the oracle buildpack?
🤦 No, that's cause I'm on an M1 Mac. I need to rebuild it on an AMD64 machine.
I've updated the image, give it another pull and try again. It should work now.
I've updated the image, give it another pull and try again. It should work now.
It does! Thanks a lot, @dmikusa! :)
Will this be updated with new JDK 21 which has been released in the meantime?
The demo image isn't going to be updated. That's just a proof of concept for the RFC.
I'm hopeful that we can get the RFC approved soon though and get all of this merged into the actual buildpack. When that happens, yes we'll absolutely be including Java 21 support.
I notice the PR discusses native-image, am I correct in understanding the same can't be used with as vanilla graalvm sdk? This might be good time to push for that support as spring 3.2 and java 21 are out so people will be looking at graalvm support with the free license.
FYI, we have the RFC basically approved but are waiting on legal clearance because this is a new license. It's taking a while, but we have to follow the CFF's rules in this regard. As soon as we get clearance, I'm going to update and get this merged.
Hello @dmikusa , I took the liberty to update your PR (rebase on main
, that included Java 21 in favor of Java 20)
Let me see if I can add the explicit warnings "YOU ACCEPTED THE LICENSE ..."
hum; I've republished my oracle-buildpack
to : docker.io/anthonydahanne/oracle:4.0.0-anthony
but unfortunately, I can't build a native app; always stuck with:
[builder] [1/8] Initializing... (4.7s @ 0.21GB)
[builder] Java version: 21.0.1+12, vendor version: Oracle GraalVM 21.0.1+12.1
[builder] Graal compiler: optimization level: 2, target machine: x86-64-v3, PGO: ML-inferred
[builder] C compiler: gcc (linux, x86_64, 11.4.0)
[builder] Garbage collector: Serial GC (max heap size: 80% of RAM)
[builder] 2 user-specific feature(s):
[builder] - com.oracle.svm.thirdparty.gson.GsonFeature
[builder] - org.springframework.aot.nativex.feature.PreComputeFieldFeature
[builder] --------------------------------------------------------------------------------
[builder] 3 experimental option(s) unlocked:
[builder] - '-H:Name' (alternative API option(s): -o io.paketo.demo.DemoApplication; origin(s): command line)
[builder] - '-H:+StaticExecutableWithDynamicLibC' (origin(s): command line)
[builder] - '-H:ReflectionConfigurationResources' (origin(s): 'META-INF/native-image/io.netty/netty-transport/native-image.properties' in 'file:///workspace/BOOT-INF/lib/netty-transport-4.1.101.Final.jar')
[builder] --------------------------------------------------------------------------------
[builder] Build resources:
[builder] - 23.59GB of memory (75.3% of 31.33GB system memory, determined at start)
[builder] - 8 thread(s) (100.0% of 8 available processor(s), determined at start)
[builder] SLF4J: No SLF4J providers were found.
[builder] SLF4J: Defaulting to no-operation (NOP) logger implementation
[builder] SLF4J: See https://www.slf4j.org/codes.html#noProviders for further details.
[builder] [2/8] Performing analysis... [] (23.8s @ 0.74GB)
[builder] 9,465 reachable types (83.0% of 11,398 total)
[builder] 12,763 reachable fields (57.1% of 22,336 total)
[builder] 47,333 reachable methods (56.9% of 83,239 total)
[builder] 2,993 types, 316 fields, and 2,091 methods registered for reflection
[builder]
[builder] Error: Classes that should be initialized at run time got initialized during image building:
[builder] ch.qos.logback.classic.Logger was unintentionally initialized at build time. To see why ch.qos.logback.classic.Logger got initialized use --trace-class-initialization=ch.qos.logback.classic.Logger
[builder] ch.qos.logback.core.status.InfoStatus was unintentionally initialized at build time. To see why ch.qos.logback.core.status.InfoStatus got initialized use --trace-class-initialization=ch.qos.logback.core.status.InfoStatus
[builder] ch.qos.logback.core.status.StatusBase was unintentionally initialized at build time. To see why ch.qos.logback.core.status.StatusBase got initialized use --trace-class-initialization=ch.qos.logback.core.status.StatusBase
[builder] ch.qos.logback.classic.Level was unintentionally initialized at build time. To see why ch.qos.logback.classic.Level got initialized use --trace-class-initialization=ch.qos.logback.classic.Level
[builder] org.slf4j.LoggerFactory was unintentionally initialized at build time. To see why org.slf4j.LoggerFactory got initialized use --trace-class-initialization=org.slf4j.LoggerFactory
[builder] ch.qos.logback.core.util.Loader was unintentionally initialized at build time. To see why ch.qos.logback.core.util.Loader got initialized use --trace-class-initialization=ch.qos.logback.core.util.Loader
[builder] ch.qos.logback.core.util.StatusPrinter was unintentionally initialized at build time. To see why ch.qos.logback.core.util.StatusPrinter got initialized use --trace-class-initialization=ch.qos.logback.core.util.StatusPrinter
[builder] To see how the classes got initialized, use --trace-class-initialization=ch.qos.logback.classic.Logger,ch.qos.logback.core.status.InfoStatus,ch.qos.logback.core.status.StatusBase,ch.qos.logback.classic.Level,org.slf4j.LoggerFactory,ch.qos.logback.core.util.Loader,ch.qos.logback.core.util.StatusPrinter
[builder] --------------------------------------------------------------------------------
[builder] 2.8s (9.6% of total time) in 154 GCs | Peak RSS: 1.51GB | CPU load: 6.79
[builder] ================================================================================
[builder] Finished generating 'io.paketo.demo.DemoApplication' in 28.7s.
[builder] unable to invoke layer creator
[builder] unable to contribute native-image layer
[builder] error running build
[builder] exit status 1
[builder] ERROR: failed to build: exit status 1
ERROR: failed to build: executing lifecycle: failed with status code: 51
~~Tell me if you're luckier than me @dmikusa ...
I run this from an Ubuntu x86_64 with:
pack build apps/native -e BP_NATIVE_IMAGE=true -e BP_JVM_VERSION=21 -b docker.io/anthonydahanne/oracle:4.0.0-anthony -b urn:cnb:builder:paketo-buildpacks/java-native-image -B paketobuildpacks/builder-jammy-tiny:latest
on
/samples/java/native-image/spring-boot-native-image-maven~~
Solved, works fine, see: https://github.com/paketo-buildpacks/oracle/pull/144#issuecomment-1843051019 and https://github.com/paketo-buildpacks/oracle/pull/144#issuecomment-1842687862
Also, wrt to explicit messaging about Oracle license, I suggest we insert the messaging both in README.md
like you told me earlier @dmikusa as well as in the logs:
@anthonydahanne the Spring app you're trying to build uses 3.1.X. Don't you need 3.2.x for Java 21 support?
Regarding the license notice, I thought the default bellsoft/liberica buildpack already has a similar one that can be adapted? It probably needs to mention the Liberica NIK EULA somewhere, no?
I pushed an update to the README to clarify the behavior now includes Native Image support. Also, I added a small blurb to the license section at the bottom. @fniephaus and @anthonydahanne let me know what you think about that. I'm not tied to the wording, I just want to make it clear the buildpack is just an installer and you as a user are responsible for ensuring compliance with all license requirements.
@fniephaus I also thought of Spring Boot 3.2, and got the same result; probably something I missed with instrumentation of classes, I'll have a deeper look tomorrow
@dmikusa thank you for updating the README.md
, looks good!
I ran successfully with Spring Boot 3.2 using spring-boot-maven-plugin + native-maven-plugin. The bindings and proxy are due to building behind corporate proxy. Here is my plugin setup:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<network>host</network>
<builder>paketobuildpacks/builder-jammy-tiny:latest</builder>
<buildpacks>
<buildpack>docker.io/anthonydahanne/oracle:4.0.0-anthony</buildpack>
<buildpack>urn:cnb:builder:paketo-buildpacks/java-native-image</buildpack>
</buildpacks>
<env>
<BP_JVM_VERSION>21</BP_JVM_VERSION>
<HTTP_PROXY>${docker.http.proxy}</HTTP_PROXY>
<HTTPS_PROXY>${docker.https.proxy}</HTTPS_PROXY>
<NO_PROXY>${docker.noProxy}</NO_PROXY>
</env>
<bindings>
<binding>
${project.build.directory}/platform/bindings/certificates:/platform/bindings/certificates
</binding>
</bindings>
</image>
</configuration>
</plugin>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
</plugin>
Thank you @mjhaugsdal !
You validated it works from the Spring Boot Maven Plugin.
This morning, I got my ideas clearer and validated it works from the pack
CLI as well:
From https://github.com/paketo-buildpacks/samples/tree/main/java/native-image/spring-boot-native-image-maven
GraalVM 17 Native Build:
pack build apps/native --env BP_MAVEN_ACTIVE_PROFILES=native -b docker.io/anthonydahanne/oracle:4.0.0-anthony -b urn:cnb:builder:paketo-buildpacks/java-native-image -B paketobuildpacks/builder-jammy-tiny:latest
GraalVM 21 Native Build:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>io.paketo</groupId>
@@ -14,7 +14,7 @@
<properties>
Would it work with spring maven plugin and packaging the container with the GraalVM JDK but without the native part?
@schrepfler Presently, no. If you were to install a JVM, it would give you Oracle's free JDK, not Oracle GraalVM JDK. Presently, this is only going to use Oracle GraalVM for building native-image.
We are aware that folks are interested in the use case you mentioned, using Oracle GraalVM as a JVM. It's on the roadmap to support but requires more work. We wanted to get this out for folks to use in the meantime.
Tested some builds from source/precompiled-jar, with Java 17 and 21. Looks good to me.
Any updates on this, we'd like to give it a try as we've seen good performance improvement locally but as we strictly use springboot with the maven plugin and delegate to paketo we don't want to go outside of it's build ecosystem.
@schrepfler please follow paketo-buildpacks/libjvm#431 for updates.
Summary
This PR adds Oracle GraalVM support to the Oracle buildpack. This allows you to use Oracle GraalVM to build your native-image applications. Presently, it does not allow you to build JVM based applications with GraalVM. Instead, it will use the Oracle JDK for this.
Use Cases
This is a short spike on how we could possibly implement https://github.com/paketo-buildpacks/rfcs/pull/294. The benefit of this approach is the simplicity and low amount of work it requires to get users to build native-image apps with Oracle GraalVM.
It does have the drawback mentioned in the commit message where you cannot at the moment select Oracle GraalVM to build JVM-based apps. It will continue to use Oracle JDK for that.
Checklist