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
*)