From e44502bca843f171645ffff02d005a9a60a732cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Oct 2026 09:45:37 +0000 Subject: [PATCH 1/3] Bump io.helidon.applications:helidon-se in /reactive/helidon Bumps io.helidon.applications:helidon-se from 4.5.4 to 27.0.1. --- updated-dependencies: - dependency-name: io.helidon.applications:helidon-se dependency-version: 27.0.1 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- reactive/helidon/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From f90d506fd6a77c6d2bc8b402b941cc4d0ea0670a Mon Sep 17 00:00:00 2001 From: Matt Raible Date: Tue, 27 Oct 2026 11:31:54 -0600 Subject: [PATCH 2/3] Fix Helidon SE 27 build: use Java 27 and replace removed Config.global() Helidon 27 is compiled for Java 27, so the Helidon workflow and the JVM Dockerfiles now use Java 27. Config.global(Config) was removed in Helidon 27, so the config is registered with Services.set(Config.class, config) as its deprecation note recommended. --- .github/workflows/helidon.yml | 4 ++-- reactive/helidon/Dockerfile | 4 ++-- reactive/helidon/Dockerfile.jlink | 2 +- reactive/helidon/README.md | 2 +- reactive/helidon/src/main/java/com/example/rest/Main.java | 3 ++- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/helidon.yml b/.github/workflows/helidon.yml index 89f1617..a1206e3 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@v5 with: distribution: 'temurin' - java-version: 25 + java-version: 27 cache: 'gradle' - name: Run tests working-directory: ./${{ matrix.app }} diff --git a/reactive/helidon/Dockerfile b/reactive/helidon/Dockerfile index db7b038..ab2df4f 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 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 WORKDIR /helidon # Copy the binary built in the 1st stage diff --git a/reactive/helidon/Dockerfile.jlink b/reactive/helidon/Dockerfile.jlink index 41e4003..a412eb8 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 as build WORKDIR /usr/share 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/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"))) From 29508eb490062ffe56b809d3e63071845db17d53 Mon Sep 17 00:00:00 2001 From: Matt Raible Date: Tue, 27 Oct 2026 12:17:37 -0600 Subject: [PATCH 3/3] Replace Helidon SE native image with a jlink image and AOT cache Helidon 27 requires Java 27, and no GraalVM release supports Java 27 yet. Helidon 27's generated projects also no longer include a native Dockerfile. Their replacement for fast startup is a jlink runtime image that includes an ahead-of-time (AOT) cache by default. - Remove Dockerfile.native and the native-image.properties file. - Build and publish mraible/helidon-reactive from Dockerfile.jlink. - Use the Oracle Linux 9 base images from Helidon 27's generated Dockerfiles. - Update build.sh, start.sh, memory.sh, the reactive demo script, and the README to build and run the jlink image. --- .github/workflows/reactive.yml | 2 +- README.md | 4 +- reactive/build.sh | 5 ++- reactive/demo.adoc | 15 +++---- reactive/helidon/Dockerfile | 4 +- reactive/helidon/Dockerfile.jlink | 4 +- reactive/helidon/Dockerfile.native | 39 ------------------- .../rest/helidon/native-image.properties | 1 - reactive/memory.sh | 5 ++- reactive/start.sh | 2 +- 10 files changed, 19 insertions(+), 62 deletions(-) delete mode 100644 reactive/helidon/Dockerfile.native delete mode 100644 reactive/helidon/src/main/resources/META-INF/native-image/com/example/rest/helidon/native-image.properties 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 ab2df4f..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:27 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:27 +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 a412eb8..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:27 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/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 *)