diff --git a/.github/workflows/helidon.yml b/.github/workflows/helidon.yml index 912e991..b61b083 100644 --- a/.github/workflows/helidon.yml +++ b/.github/workflows/helidon.yml @@ -34,11 +34,11 @@ jobs: steps: - name: Checkout uses: actions/checkout@v7 - - name: Configure Java 25 + - name: Configure Java 27 uses: actions/setup-java@v6 with: distribution: 'temurin' - java-version: 25 + java-version: 27 cache: 'gradle' - name: Run tests working-directory: ./${{ matrix.app }} diff --git a/.github/workflows/reactive.yml b/.github/workflows/reactive.yml index bb94213..74ff627 100644 --- a/.github/workflows/reactive.yml +++ b/.github/workflows/reactive.yml @@ -49,7 +49,7 @@ jobs: - name: Build Helidon project run: | cd reactive/helidon - docker build -t helidon -f Dockerfile.native . + docker build -t helidon -f Dockerfile.jlink . docker tag helidon:latest mraible/helidon-reactive:latest shell: bash diff --git a/README.md b/README.md index 333d5d0..80f5c94 100644 --- a/README.md +++ b/README.md @@ -79,14 +79,14 @@ You can also build and run each example as a native app. - Micronaut: `./gradlew nativeCompile` - Quarkus: `quarkus build --native` - Spring Boot: `./gradlew nativeCompile` -- Helidon: `mvn package -Pnative-image` +- Helidon: `mvn package -Pnative-image` (imperative) or `mvn package -Pjlink-image` (reactive, which uses a jlink image because no GraalVM release supports Java 27 yet) Then, start each app as a native executable. - Micronaut: `./build/native/nativeCompile/app` - Quarkus: `./build/quarkus-1.0.0-SNAPSHOT-runner` - Spring Boot: `./build/native/nativeCompile/spring-boot` -- Helidon: `./target/helidon` +- Helidon: `./target/helidon` (imperative) or `./target/helidon-jri/bin/start` (reactive) ## Links diff --git a/reactive/build.sh b/reactive/build.sh index 15c26a8..a322e80 100755 --- a/reactive/build.sh +++ b/reactive/build.sh @@ -18,5 +18,6 @@ cd ../quarkus && ./gradlew build -Dquarkus.package.type=native echo "Building Spring Boot..." cd ../spring-boot && ./gradlew nativeCompile -echo "Building Helidon..." -cd ../helidon && mvn package -Pnative-image +echo "Building Helidon (jlink image with AOT cache, requires Java 27)..." +sdk use java 27.0.0.0+35-tem +cd ../helidon && mvn package -Pjlink-image diff --git a/reactive/demo.adoc b/reactive/demo.adoc index daab7b3..0dd83a5 100644 --- a/reactive/demo.adoc +++ b/reactive/demo.adoc @@ -419,22 +419,17 @@ security: http :8080/hello Authorization:"Bearer $TOKEN" -=== Build a native Helidon app with GraalVM +=== Build a Helidon jlink image with an AOT cache -. Update `src/main/resources/META-INF/native-image/com.example.rest/helidon/native-image.properties` so native compilation will work with Java 21. -+ -[source,properties] ----- -Args=--initialize-at-build-time=com.example.rest --enable-url-protocols=https ----- +Helidon 27 requires Java 27, and no GraalVM release supports Java 27 yet, so this app uses a custom Java runtime image with an ahead-of-time (AOT) cache instead of a native executable. -. Compile your Helidon app into a native executable using the `native-image` profile: +. Build the runtime image using the `jlink-image` profile: - mvn package -Pnative-image + mvn package -Pjlink-image . Start your Helidon app: - ./target/helidon + ./target/helidon-jri/bin/start . Test your API with an access token. diff --git a/reactive/helidon/Dockerfile b/reactive/helidon/Dockerfile index db7b038..a57e18c 100644 --- a/reactive/helidon/Dockerfile +++ b/reactive/helidon/Dockerfile @@ -1,6 +1,6 @@ # 1st stage, build the app -FROM container-registry.oracle.com/java/openjdk:21 as build +FROM container-registry.oracle.com/java/openjdk:27-oraclelinux9 AS build # Install maven WORKDIR /usr/share @@ -27,7 +27,7 @@ RUN mvn package -DskipTests RUN echo "done!" # 2nd stage, build the runtime image -FROM container-registry.oracle.com/java/openjdk:21 +FROM container-registry.oracle.com/java/openjdk:27-oraclelinux9 WORKDIR /helidon # Copy the binary built in the 1st stage diff --git a/reactive/helidon/Dockerfile.jlink b/reactive/helidon/Dockerfile.jlink index 41e4003..756ac2f 100644 --- a/reactive/helidon/Dockerfile.jlink +++ b/reactive/helidon/Dockerfile.jlink @@ -1,6 +1,6 @@ # 1st stage, build the app -FROM container-registry.oracle.com/java/openjdk:21 as build +FROM container-registry.oracle.com/java/openjdk:27-oraclelinux9 AS build WORKDIR /usr/share @@ -28,7 +28,7 @@ RUN echo "done!" # 2nd stage, build the final image with the JRI built in the 1st stage -FROM debian:stretch-slim +FROM container-registry.oracle.com/os/oraclelinux:9-slim WORKDIR /helidon COPY --from=build /helidon/target/helidon-jri ./ ENTRYPOINT ["/bin/bash", "/helidon/bin/start"] diff --git a/reactive/helidon/Dockerfile.native b/reactive/helidon/Dockerfile.native deleted file mode 100644 index 18529aa..0000000 --- a/reactive/helidon/Dockerfile.native +++ /dev/null @@ -1,39 +0,0 @@ - -# 1st stage, build the app -FROM ghcr.io/graalvm/graalvm-community:25-ol9 as build - -WORKDIR /usr/share - -# Install maven -RUN set -x && \ - curl -O https://archive.apache.org/dist/maven/maven-3/3.9.9/binaries/apache-maven-3.9.9-bin.tar.gz && \ - tar -xvf apache-maven-*-bin.tar.gz && \ - rm apache-maven-*-bin.tar.gz && \ - mv apache-maven-* maven && \ - ln -s /usr/share/maven/bin/mvn /bin/ - -WORKDIR /helidon - -# Create a first layer to cache the "Maven World" in the local repository. -# Incremental docker builds will always resume after that, unless you update -# the pom -ADD pom.xml . -RUN mvn package -Pnative-image -Dnative.image.skip -Dmaven.test.skip -Declipselink.weave.skip - -# Do the Maven build! -# Incremental docker builds will resume here when you change sources -ADD src src -RUN mvn package -Pnative-image -Dnative.image.buildStatic -DskipTests - -RUN echo "done!" - -# 2nd stage, build the runtime image -FROM scratch -WORKDIR /helidon - -# Copy the binary built in the 1st stage -COPY --from=build /helidon/target/helidon . - -ENTRYPOINT ["./helidon"] - -EXPOSE 8080 diff --git a/reactive/helidon/README.md b/reactive/helidon/README.md index d84dcdb..b7081e5 100644 --- a/reactive/helidon/README.md +++ b/reactive/helidon/README.md @@ -5,7 +5,7 @@ Sample Helidon SE project that includes multiple REST operations. ## Build and run -With JDK21 +With JDK 27 ```bash mvn package java -jar target/helidon.jar diff --git a/reactive/helidon/pom.xml b/reactive/helidon/pom.xml index d5fe5a7..07d05d4 100644 --- a/reactive/helidon/pom.xml +++ b/reactive/helidon/pom.xml @@ -6,7 +6,7 @@ io.helidon.applications helidon-se - 4.5.4 + 27.0.1 com.example.rest diff --git a/reactive/helidon/src/main/java/com/example/rest/Main.java b/reactive/helidon/src/main/java/com/example/rest/Main.java index ab15a51..b4a58bc 100644 --- a/reactive/helidon/src/main/java/com/example/rest/Main.java +++ b/reactive/helidon/src/main/java/com/example/rest/Main.java @@ -3,6 +3,7 @@ import com.example.rest.resource.HelloResource; import io.helidon.config.Config; import io.helidon.logging.common.LogConfig; +import io.helidon.service.registry.Services; import io.helidon.webserver.WebServer; import io.helidon.webserver.WebServerConfig; import io.helidon.webserver.security.SecurityHttpFeature; @@ -28,7 +29,7 @@ public static void main(String[] args) { static void setup(WebServerConfig.Builder server) { Config config = Config.create(); - Config.global(config); + Services.set(Config.class, config); server.routing(routing -> routing .addFeature(SecurityHttpFeature.create(config.get("security.web-server"))) diff --git a/reactive/helidon/src/main/resources/META-INF/native-image/com/example/rest/helidon/native-image.properties b/reactive/helidon/src/main/resources/META-INF/native-image/com/example/rest/helidon/native-image.properties deleted file mode 100644 index 451cd4e..0000000 --- a/reactive/helidon/src/main/resources/META-INF/native-image/com/example/rest/helidon/native-image.properties +++ /dev/null @@ -1 +0,0 @@ -Args=--initialize-at-build-time=com.example.rest --enable-url-protocols=https diff --git a/reactive/memory.sh b/reactive/memory.sh index 3d1ce3a..bef4906 100755 --- a/reactive/memory.sh +++ b/reactive/memory.sh @@ -22,7 +22,8 @@ case "$selected_app" in start_command="./spring-boot/build/native/nativeCompile/spring-boot" ;; "helidon") - start_command="./helidon/target/helidon" + start_command="./helidon/target/helidon-jri/bin/start" + process_name="helidon-jri" ;; # Add more cases for other apps as needed *) @@ -32,7 +33,7 @@ case "$selected_app" in esac # Extract the executable name using basename -executable=$(basename "$start_command") +executable=${process_name:-$(basename "$start_command")} # Define memory function memory() { diff --git a/reactive/start.sh b/reactive/start.sh index 3ab6acc..d2703b2 100755 --- a/reactive/start.sh +++ b/reactive/start.sh @@ -21,7 +21,7 @@ case "$selected_app" in start_command="./spring-boot/build/native/nativeCompile/spring-boot" ;; "helidon") - start_command="./helidon/target/helidon" + start_command="./helidon/target/helidon-jri/bin/start" ;; # Add more cases for other apps as needed *)