-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Open
Labels
Description
Describe the Issue
Using Graalvm-CE 24 with micronuat application with below dependencies
plugins {
id("io.micronaut.application") version "4.5.3"
id("com.gradleup.shadow") version "8.3.6"
id("io.micronaut.aot") version "4.5.3"
}
version = "0.1"
group = "#######"
repositories {
mavenCentral()
}
dependencies {
annotationProcessor("io.micronaut:micronaut-http-validation")
annotationProcessor("io.micronaut.openapi:micronaut-openapi")
annotationProcessor("io.micronaut.serde:micronaut-serde-processor")
annotationProcessor("io.micronaut.validation:micronaut-validation-processor")
implementation("io.micronaut.validation:micronaut-validation")
implementation("jakarta.validation:jakarta.validation-api")
implementation("io.micronaut.gcp:micronaut-gcp-logging")
implementation("io.micronaut.serde:micronaut-serde-jackson")
implementation("com.google.cloud:google-cloud-firestore:3.31.6")
implementation("io.micronaut:micronaut-management")
implementation("com.nimbusds:nimbus-jose-jwt:10.3")
implementation("io.micronaut:micronaut-http-client")
compileOnly("io.micronaut.openapi:micronaut-openapi-annotations")
runtimeOnly("ch.qos.logback:logback-classic")
testImplementation("io.micronaut:micronaut-http-client")
}
application {
mainClass = "xxx.xxxx.XXXXXX"
}
java {
sourceCompatibility = JavaVersion.toVersion("24")
targetCompatibility = JavaVersion.toVersion("24")
}
graalvmNative.toolchainDetection = true
micronaut {
runtime("netty")
testRuntime("junit5")
processing {
incremental(true)
annotations("xxxx.xxxxx.*")
}
aot {
optimizeServiceLoading = false
convertYamlToJava = false
precomputeOperations = true
cacheEnvironment = true
optimizeClassLoading = true
deduceEnvironment = true
optimizeNetty = true
replaceLogbackXml = true
}
}
tasks.named<io.micronaut.gradle.docker.NativeImageDockerfile>("optimizedDockerfileNative") {
jdkVersion = "24"
baseImage = "gcr.io/distroless/base-debian12](http://gcr.io/distroless/base-debian12)"
}
Steps to follow
For optimized native image
- Step 1 - `./gradlew clean`
- Step 2 - `./gradlew build`
- Step 3 - `./gradlew nativeOptimizedCompile` // This step in not required in CI, because docker file has this step
- Step 4 - `./gradlew optimizedDockerfileNative`
- Step 5 - `./gradlew optimizedBuildNativelayersTask`
- Step 6 - `./gradlew optimizeddockerPrepareContext`
The docker file generated is as below
FROM [ghcr.io/graalvm/native-image-community:24-ol9](http://ghcr.io/graalvm/native-image-community:24-ol9) AS graalvm
WORKDIR /home/app
COPY --link layers/libs /home/app/libs
COPY --link layers/app /home/app/
RUN mkdir /home/app/config-dirs
RUN mkdir -p /home/app/config-dirs/generateResourcesConfigFile
RUN mkdir -p /home/app/config-dirs/io.netty\netty-common\4.1.115.Final
RUN mkdir -p /home/app/config-dirs/io.netty\netty-transport\4.1.115.Final
RUN mkdir -p /home/app/config-dirs/ch.qos.logback.contrib\logback-json-classic\0.1.5
RUN mkdir -p /home/app/config-dirs/ch.qos.logback\logback-classic\1.4.9
RUN mkdir -p /home/app/config-dirs/org.apache.httpcomponents\httpclient\4.5.14
RUN mkdir -p /home/app/config-dirs/com.google.protobuf\protobuf-java-util\3.21.12
RUN mkdir -p /home/app/config-dirs/io.grpc\grpc-core\1.69.0
COPY --link config-dirs/generateResourcesConfigFile /home/app/config-dirs/generateResourcesConfigFile
COPY --link config-dirs/io.netty/netty-common/4.1.115.Final /home/app/config-dirs/io.netty/netty-common/4.1.115.Final
COPY --link config-dirs/io.netty/netty-transport/4.1.115.Final /home/app/config-dirs/io.netty/netty-transport/4.1.115.Final
COPY --link config-dirs/ch.qos.logback.contrib/logback-json-classic/0.1.5 /home/app/config-dirs/ch.qos.logback.contrib/logback-json-classic/0.1.5
COPY --link config-dirs/ch.qos.logback/logback-classic/1.4.9 /home/app/config-dirs/ch.qos.logback/logback-classic/1.4.9
COPY --link config-dirs/org.apache.httpcomponents/httpclient/4.5.14 /home/app/config-dirs/org.apache.httpcomponents/httpclient/4.5.14
COPY --link config-dirs/com.google.protobuf/protobuf-java-util/3.21.12 /home/app/config-dirs/com.google.protobuf/protobuf-java-util/3.21.12
COPY --link config-dirs/io.grpc/grpc-core/1.69.0 /home/app/config-dirs/io.grpc/grpc-core/1.69.0
RUN native-image --exclude-config .*/libs/netty-buffer-4.1.119.Final.jar ^/META-INF/native-image/.* --exclude-config .*/libs/netty-common-4.1.119.Final.jar ^/META-INF/native-image/.* --exclude-config .*/libs/netty-transport-4.1.119.Final.jar ^/META-INF/native-image/.* --exclude-config .*/libs/netty-codec-http-4.1.119.Final.jar ^/META-INF/native-image/.* --exclude-config .*/libs/grpc-core-1.71.0.jar ^/META-INF/native-image/.* --exclude-config .*/libs/netty-codec-http2-4.1.119.Final.jar ^/META-INF/native-image/.* --exclude-config .*/libs/netty-handler-4.1.119.Final.jar ^/META-INF/native-image/.* -cp /home/app/libs/*.jar:/home/app/resources:/home/app/application.jar --no-fallback -o application -H:ConfigurationFileDirectories=/home/app/config-dirs/generateResourcesConfigFile,/home/app/config-dirs/io.netty/netty-common/4.1.115.Final,/home/app/config-dirs/io.netty/netty-buffer/4.1.80.Final,/home/app/config-dirs/io.netty/netty-transport/4.1.115.Final,/home/app/config-dirs/io.netty/netty-codec-http/4.1.80.Final,/home/app/config-dirs/io.netty/netty-handler/4.1.80.Final,/home/app/config-dirs/io.netty/netty-codec-http2/4.1.80.Final,/home/app/config-dirs/ch.qos.logback.contrib/logback-json-classic/0.1.5,/home/app/config-dirs/ch.qos.logback/logback-classic/1.4.9,/home/app/config-dirs/org.apache.httpcomponents/httpclient/4.5.14,/home/app/config-dirs/com.google.protobuf/protobuf-java-util/3.21.12,/home/app/config-dirs/io.grpc/grpc-core/1.69.0 xxx.health.MsAddinApplication -H:+StaticExecutableWithDynamicLibC
FROM [gcr.io/distroless/base-debian12](http://artifactory.devops.xxx-aws.com.au/xxx-docker-gcr-remote-prod/distroless/base-debian12)
EXPOSE 8080
COPY --link --from=graalvm /home/app/application /app/application
ENTRYPOINT ["/app/application"]
The Github action to build the native image for Micronaut application, takes too long and Github action keeps failling, with a custom runner as custom-runners-linux with low configuration
#9 [graalvm 2/23] WORKDIR /home/app
#9 DONE 3.4s
#10 [graalvm 3/23] COPY --link layers/libs /home/app/libs
#10 DONE 0.5s
#11 [graalvm 4/23] COPY --link layers/app /home/app/
#11 DONE 0.0s
#12 [graalvm 5/23] COPY --link layers/resources /home/app/resources
#12 DONE 0.0s
#13 [graalvm 6/23] RUN mkdir /home/app/config-dirs
#13 DONE 0.2s
#14 [graalvm 7/23] RUN mkdir -p /home/app/config-dirs/generateResourcesConfigFile
#14 DONE 0.3s
#15 [graalvm 8/23] RUN mkdir -p /home/app/config-dirs/io.netty/netty-common/4.1.115.Final
#15 DONE 0.4s
#16 [graalvm 9/23] RUN mkdir -p /home/app/config-dirs/io.netty/netty-transport/4.1.115.Final
#16 DONE 0.4s
#17 [graalvm 10/23] RUN mkdir -p /home/app/config-dirs/ch.qos.logback.contrib/logback-json-classic/0.1.5
#17 DONE 0.3s
#18 [graalvm 11/23] RUN mkdir -p /home/app/config-dirs/ch.qos.logback/logback-classic/1.4.9
#18 DONE 0.3s
#19 [graalvm 12/23] RUN mkdir -p /home/app/config-dirs/org.apache.httpcomponents/httpclient/4.5.14
#19 DONE 0.3s
#20 [graalvm 13/23] RUN mkdir -p /home/app/config-dirs/com.google.protobuf/protobuf-java-util/3.21.12
#20 DONE 0.3s
#21 [graalvm 14/23] RUN mkdir -p /home/app/config-dirs/io.grpc/grpc-core/1.69.0
#21 DONE 0.4s
#22 [graalvm 15/23] COPY --link config-dirs/generateResourcesConfigFile /home/app/config-dirs/generateResourcesConfigFile
#22 DONE 0.0s
#23 [graalvm 16/23] COPY --link config-dirs/io.netty/netty-common/4.1.115.Final /home/app/config-dirs/io.netty/netty-common/4.1.115.Final
#23 DONE 0.0s
#24 [graalvm 17/23] COPY --link config-dirs/io.netty/netty-transport/4.1.115.Final /home/app/config-dirs/io.netty/netty-transport/4.1.115.Final
#24 DONE 0.0s
#25 [graalvm 18/23] COPY --link config-dirs/ch.qos.logback.contrib/logback-json-classic/0.1.5 /home/app/config-dirs/ch.qos.logback.contrib/logback-json-classic/0.1.5
#25 DONE 0.0s
#26 [graalvm 19/23] COPY --link config-dirs/ch.qos.logback/logback-classic/1.4.9 /home/app/config-dirs/ch.qos.logback/logback-classic/1.4.9
#26 DONE 0.0s
#27 [graalvm 20/23] COPY --link config-dirs/org.apache.httpcomponents/httpclient/4.5.14 /home/app/config-dirs/org.apache.httpcomponents/httpclient/4.5.14
#27 DONE 0.0s
#28 [graalvm 21/23] COPY --link config-dirs/com.google.protobuf/protobuf-java-util/3.21.12 /home/app/config-dirs/com.google.protobuf/protobuf-java-util/3.21.12
#28 DONE 0.0s
#29 [graalvm 22/23] COPY --link config-dirs/io.grpc/grpc-core/1.69.0 /home/app/config-dirs/io.grpc/grpc-core/1.69.0
#29 DONE 0.0s
#30 [graalvm 23/23] RUN native-image --exclude-config .*/libs/netty-buffer-4.1.119.Final.jar ^/META-INF/native-image/.* --exclude-config .*/libs/netty-common-4.1.119.Final.jar ^/META-INF/native-image/.* --exclude-config .*/libs/netty-transport-4.1.119.Final.jar ^/META-INF/native-image/.* --exclude-config .*/libs/netty-codec-http-4.1.119.Final.jar ^/META-INF/native-image/.* --exclude-config .*/libs/grpc-core-1.71.0.jar ^/META-INF/native-image/.* --exclude-config .*/libs/netty-codec-http2-4.1.119.Final.jar ^/META-INF/native-image/.* --exclude-config .*/libs/netty-handler-4.1.119.Final.jar ^/META-INF/native-image/.* -cp /home/app/libs/*.jar:/home/app/resources:/home/app/application.jar --no-fallback -o application -H:ConfigurationFileDirectories=/home/app/config-dirs/generateResourcesConfigFile,/home/app/config-dirs/io.netty/netty-common/4.1.115.Final,/home/app/config-dirs/io.netty/netty-buffer/4.1.80.Final,/home/app/config-dirs/io.netty/netty-transport/4.1.115.Final,/home/app/config-dirs/io.netty/netty-codec-ht
#30 0.251 Warning: The option '-H:+StaticExecutableWithDynamicLibC' is experimental and must be enabled via '-H:+UnlockExperimentalVMOptions' in the future.
#30 0.251 Warning: Please re-evaluate whether any experimental option is required, and either remove or unlock it. The build output lists all active experimental options, including where they come from and possible alternatives. If you think an experimental option should be considered as stable, please file an issue.
#30 11.92 ========================================================================================================================
#30 11.92 GraalVM Native Image: Generating 'application' (static executable)...
#30 11.92 ========================================================================================================================
#30 11.92 For detailed information and explanations on the build output, visit:
#30 11.92 https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/BuildOutput.md
#30 11.92 ------------------------------------------------------------------------------------------------------------------------
#30 16.75 [1/8] Initializing... (15.2s @ 0.25GB)
#30 16.75 Java version: 24.0.1+9, vendor version: GraalVM CE 24.0.1+9.1
#30 16.75 Graal compiler: optimization level: 2, target machine: x86-64-v3
#30 16.75 C compiler: gcc (redhat, x86_64, 11.5.0)
#30 16.75 Garbage collector: Serial GC (max heap size: 80% of RAM)
#30 16.75 5 user-specific feature(s):
#30 16.75 - com.google.api.gax.grpc.nativeimage.GrpcNettyFeature
#30 16.75 - com.google.api.gax.nativeimage.GoogleJsonClientFeature
#30 16.75 - com.google.api.gax.nativeimage.OpenCensusFeature
#30 16.75 - com.oracle.svm.thirdparty.gson.GsonFeature
#30 16.75 - io.micronaut.core.io.service.ServiceLoaderFeature
#30 16.75 ------------------------------------------------------------------------------------------------------------------------
#30 16.75 1 experimental option(s) unlocked:
#30 16.75 - '-H:+StaticExecutableWithDynamicLibC' (origin(s): command line)
#30 16.75 ------------------------------------------------------------------------------------------------------------------------
#30 16.75 Build resources:
#30 16.75 - 5.70GB of memory (75.6% of 7.55GB system memory, determined at start)
#30 16.75 - 2 thread(s) (100.0% of 2 available processor(s), determined at start)
#30 17.20 Jun 20, 2025 3:10:19 AM com.google.api.gax.nativeimage.NativeImageUtils registerClassForReflection
#30 17.20 WARNING: Failed to find io.grpc.netty.shaded.io.netty.channel.ProtocolNegotiators on the classpath for reflection.
#30 224.5 [2/8] Performing analysis... [*****] (207.0s @ 2.47GB)
#30 224.5 25,526 reachable types (90.8% of 28,125 total)
#30 224.5 46,669 reachable fields (61.5% of 75,889 total)
#30 224.7 195,663 reachable methods (65.0% of 301,027 total)
#30 224.7 10,145 types, 2,248 fields, and 54,201 methods registered for reflection
#30 224.7 83 types, 84 fields, and 69 methods registered for JNI access
#30 224.7 4 native libraries: dl, pthread, rt, z
#30 248.7 [3/8] Building universe... (24.0s @ 3.21GB)
#30 271.7 [4/8] Parsing methods... [*****] (23.0s @ 1.79GB)
#30 283.4 [5/8] Inlining methods... [***] (11.0s @ 2.25GB)
#30 472.2 [6/8] Compiling methods... [*************] (188.8s @ 2.59GB)
#30 519.4 [7/8] Layouting methods... [*******] (47.1s @ 3.24GB)
Using the latest version of GraalVM can resolve many issues.
- I tried with the latest version of GraalVM.
GraalVM Version
Graalvm 24
Operating System and Version
Linux on Github action
Build Command
Github action
build-java-app:
name: Java Build and Test
runs-on: custom-runners-linux
steps:
- uses: actions/checkout@v4
- name: Setup Graalvm
uses: graalvm/setup-graalvm@v1
with:
java-version: '24'
distribution: 'graalvm-community'
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Check Java version and vendor
run: java -version
- name: Make gradlew executable
working-directory: ${{ env.JAVA_API_PATH }}
run: chmod +x ./gradlew
- name: Clean Build & Test
working-directory: ${{ env.JAVA_API_PATH }}
run: ./gradlew clean build test
- name: Build Native layers Task
working-directory: ${{ env.JAVA_API_PATH }}
run: ./gradlew buildNativelayersTask
- name: Docker Prepare Context
working-directory: ${{ env.JAVA_API_PATH }}
run: ./gradlew dockerPrepareContext
- name: Docker Prepare Context
working-directory: ${{ env.JAVA_API_PATH }}
run: ./gradlew dockerfileNative
- name: Upload build files
uses: actions/upload-artifact@v4
with:
name: published-java-app
path: ${{ env.JAVA_BUILD_DIR }}
Then I have a docker build command in another Job as below which takes the files from above
dockerBuildPush:
name: Docker Build & Push
runs-on: custom-runners-linux
needs: build-java-app
defaults:
run:
shell: bash
steps:
- name: Download build files
uses: actions/download-artifact@v4
with:
name: published-java-app
path: ${{ env.JAVA_BUILD_DIR }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
-
name: Build and push
uses: docker/build-push-action@v6
with:
push: false
tags: user/app:latest
docker buildx build -f Dockerfile -t `${app-version_numer}` .
Expected Behavior
The build process shouldn't take too long
Actual Behavior
The whole progress takes forever, keeps failing
Github Runner
Run echo "Memory Info:"
#step:6:24)Memory Info:
total used free shared buff/cache available
#step:6:26)Mem: 7.5Gi 669Mi 4.4Gi 62Mi 2.5Gi 6.6Gi
Swap: 0B 0B 0B
Run echo "CPU Info:"
Info:
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Address sizes: 48 bits physical, 48 bits virtual
Byte Order: Little Endian
CPU(s): 2
On-line CPU(s) list: 0,1
Vendor ID: AuthenticAMD
Model name: AMD EPYC 7R13 Processor
CPU family: 25
Model: 1
Thread(s) per core: 2
Core(s) per socket: 1
Socket(s): 1
Stepping: 1
BogoMIPS: 5299.99
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc cpuid extd_apicid aperfmperf tsc_known_freq pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm cmp_legacy cr8_legacy abm sse4a misalignsse 3dnowprefetch topoext invpcid_single ssbd ibrs ibpb stibp vmmcall fsgsbase bmi1 avx2 smep bmi2 invpcid rdseed adx smap clflushopt clwb sha_ni xsaveopt xsavec xgetbv1 clzero xsaveerptr rdpru wbnoinvd arat npt nrip_save vaes vpclmulqdq rdpid
Hypervisor vendor: KVM
Virtualization type: full
L1d cache: 32 KiB (1 instance)
L1i cache: 32 KiB (1 instance)
L2 cache: 512 KiB (1 instance)
L3 cache: 4 MiB (1 instance)
NUMA node(s): 1
NUMA node0 CPU(s): 0,1
Vulnerability Gather data sampling: Not affected
Vulnerability Itlb multihit: Not affected
Vulnerability L1tf: Not affected
Vulnerability Mds: Not affected