GraalVM Advisory Board Linux Foundation Cloud Native Computing Foundation Founded in 2017 by Java and Linux experts with 15+ years of experience working at Sun/Oracle.
s docker compose logs chat-api bot-assistant | grep Started Started BotAssistantApplication in 2.108 seconds (process running for 3.181) Started ChatApiApplication in 2.83 seconds (process running for 3.469)
loop! Need faster rollout for faster feedback The longer the start, the slower the rollout Maybe Java is not cut out for the cloud? Maybe it’s not too late to migrate to Go?
from the archive Even better with Spring AOT (load even more classes!) Considerations: Use the same JVM Use the same classpath Bigger Docker image due to the archive Legal JVM Dopes Fo Legal JVM Dopes Fo… …
from the archive Even better with Spring AOT (load even more classes!) Considerations: Use the same JVM Use the same classpath Bigger Docker image due to the archive Let's take it for a spin! Legal JVM Dopes Fo Legal JVM Dopes Fo… …
Class Loading & Linking (JDK 24) Improve startup time by making the classes of an application instantly available, in a loaded and linked state, when the HotSpot Java Virtual Machine starts. Achieve this by monitoring the application during one run and storing the loaded and linked forms of all classes in a cache for use in subsequent runs. Lay a foundation for future improvements to both startup and warmup time.
placeholder RUN tar -zxvf java.tar.gz && mv /jdk-24 /java RUN apk add tar FROM bellsoft/alpaquita-linux-base:glibc AS builder ARG project WORKDIR /app COPY --from=downloader /java /java ADD ../pom.xml ./ ADD ${project} /app/${project} ENV JAVA_HOME=/java \ project=${project} RUN cd ${project} && ./mvnw package FROM bellsoft/alpaquita-linux-base:glibc AS optimizer ARG project
./ ADD ${project} /app/${project} ENV JAVA_HOME=/java \ RUN cd ${project} && ./mvnw package p / g / y /j g j p RUN apk add tar RUN tar -zxvf java.tar.gz && mv /jdk-24 /java ARG project WORKDIR /app project=${project} FROM bellsoft/alpaquita-linux-base:glibc AS optimizer ARG project WORKDIR /app f b ild / /${ j }/ * j j
/java /java RUN /java/bin/java -Djarmode=tools -jar app.jar extract --layers --destination extracted _ /j \ project=${project} RUN cd ${project} && ./mvnw package ARG project WORKDIR /app ENV project=${project} FROM bellsoft/alpaquita-linux-base:glibc AS runner RUN apk add curl WORKDIR /app f d l d /j /j
header not found at org.springframework.boot.loader.ExecutableArchiveLauncher.<init>(ExecutableArchiveLaun at org.springframework.boot.loader.JarLauncher.<init>(JarLauncher.java:42) at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65) Caused by: java.util.zip.ZipException: zip END header not found
thread "main" java.lang.IllegalStateException: at org.springframework.boot.loader.ExecutableArchiveLauncher.<init>(ExecutableArchiveLaun at org.springframework.boot.loader.JarLauncher.<init>(JarLauncher.java:42) at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65) Caused by: java.util.zip.ZipException: zip END header not found
build the image. Maven plugin calls native-image java -jar under the hood but uses lots of flags that solve problems like the one above. Alright, let's try with a plugin!
time got initialized during image building: com.ctc.wstx.api.CommonConfig was unintentionally initialized at build time. com.ctc.wstx.stax.WstxInputFactory was unintentionally initialized at build time. com.ctc.wstx.api.ReaderConfig was unintentionally initialized at build time. com.ctc.wstx.util.DefaultXmlSymbolTable was unintentionally initialized at build time. To see how the classes got initialized, use --trace-class-initialization=com.ctc.wstx.api.CommonConfig,com.ctc.wstx.stax.WstxInputFactory,com
time got initialized during image building: To see how the classes got initialized, use --trace-class-initialization=com.ctc.wstx.api.CommonConfig,com.ctc.wstx.stax.WstxInputFactory,com com.ctc.wstx.api.CommonConfig was unintentionally initialized at build time. com.ctc.wstx.stax.WstxInputFactory was unintentionally initialized at build time. com.ctc.wstx.api.ReaderConfig was unintentionally initialized at build time. com.ctc.wstx.util.DefaultXmlSymbolTable was unintentionally initialized at build time.
run time got initialized during image building: com.ctc.wstx.api.CommonConfig was unintentionally initialized at build time. org.springframework.http.codec.xml.XmlEventDecoder caused initialization of this class with the following trace: at com.ctc.wstx.api.CommonConfig.<clinit>(CommonConfig.java:59) at com.ctc.wstx.stax.WstxInputFactory.<init>(WstxInputFactory.java:149) at java.lang.invoke.DirectMethodHandle$Holder.newInvokeSpecial(DirectMethodHandle$Holder) at java.lang.invoke.Invokers$Holder.invokeExact_MT(Invokers$Holder) at jdk.internal.reflect.DirectConstructorHandleAccessor.invokeImpl(DirectConstructorHandle at jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandl
of this class Error: Classes that should be initialized at run time got initialized during image building: com.ctc.wstx.api.CommonConfig was unintentionally initialized at build time. with the following trace: at com.ctc.wstx.api.CommonConfig.<clinit>(CommonConfig.java:59) at com.ctc.wstx.stax.WstxInputFactory.<init>(WstxInputFactory.java:149) at java.lang.invoke.DirectMethodHandle$Holder.newInvokeSpecial(DirectMethodHandle$Holder) at java.lang.invoke.Invokers$Holder.invokeExact_MT(Invokers$Holder) at jdk.internal.reflect.DirectConstructorHandleAccessor.invokeImpl(DirectConstructorHandle at jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandl
that should be initialized at run time got initialized during image building: com.ctc.wstx.api.CommonConfig was unintentionally initialized at build time. To see why com.ctc.w com.ctc.wstx.stax.WstxInputFactory was unintentionally initialized at build time. To see why com. com.ctc.wstx.api.ReaderConfig was unintentionally initialized at build time. To see why com.ctc.ws com.ctc.wstx.util.DefaultXmlSymbolTable was unintentionally initialized at build time. To see why To see how the classes got initialized, use --trace-class-initialization=com.ctc.wstx.api.CommonCo
option. This mode requires only the classes that are stored in the image heap to be marked with –initialize-at- build-time. This effectively reduces the number of configuration entries necessary to achieve build-time initialization. Note that --strict-image-heap is enabled by default in Native Image starting from GraalVM for JDK 22.
jdk.jfr.internal.JVM.isExcluded(Ljava/lang/Class;)Z [symbol: Java_jdk_jfr_internal_JVM_isExcluded or Java_jdk_jfr_internal_JVM_isExcluded__Ljava_lang_Class_2] at org.graalvm.nativeimage.builder/com.oracle.svm.core.jni.access.JNINativeLinkage.getOrF at org.graalvm.nativeimage.builder/com.oracle.svm.core.jni.JNIGeneratedMethodSupport.nativ at [email protected]/jdk.jfr.internal.JVM.isExcluded(Native Method) ~[na:na] at [email protected]/jdk.jfr.internal.MetadataRepository.register(MetadataRepository
Spring creates a custom JFR event java.lang.UnsatisfiedLinkError: jdk.jfr.internal.JVM.isExcluded(Ljava/lang/Class;)Z [symbol: Java_jdk_jfr_internal_JVM_isExcluded or Java_jdk_jfr_internal_JVM_isExcluded__Ljava_lang_Class_2] 2025-04-11T12:25:33.511+03:00 ERROR 64619 --- [bot-assistant] [nio-8081-exec-2] o.a.c.c.C.[.[.[/] at org.graalvm.nativeimage.builder/com.oracle.svm.core.jni.access.JNINativeLinkage.getOrF at org.graalvm.nativeimage.builder/com.oracle.svm.core.jni.JNIGeneratedMethodSupport.nativ at [email protected]/jdk.jfr.internal.JVM.isExcluded(Native Method) ~[na:na] at [email protected]/jdk.jfr.internal.MetadataRepository.register(MetadataRepository
53.2s (13.5% of total time) in 2385 GCs | Peak RSS: 6.77GB | CPU load: 520.7 --------------------------------------------------------------------------------------------- 520.7 Produced artifacts: 520.7 /app/bot-assistant/target/native/svm_err_b_20250415T153317.420_pid287.md (build_info) 520.7 ============================================================================================= 520.7 Failed generating 'bot' after 6m 32s. 520.7 520.7 The build process encountered an unexpected error: 520.7
Checkpoint) Project researches coordination of Java programs with mechanisms to checkpoint (make an image of, snapshot) a Java instance while it is executing. Restoring from the image could be a solution to some of the problems with the start-up and warm-up times. The primary aim of the Project is to develop a new standard mechanism-agnostic API to notify Java programs about the checkpoint and restore events. Other research activities will include, but will not be limited to, integration with existing checkpoint/restore mechanisms and development of new ones, changes to JVM and JDK to make images smaller and ensure they are correct. https://openjdk.org/projects/crac/
// This is a part of the saved state long startTime = System.currentTimeMillis(); for(int counter: IntStream.range(1, 10000).toArray()) { Thread.sleep(1000); long currentTime = System.currentTimeMillis(); System.out.println("Counter: " + counter + "(passed " + (currentTime-startTime) + " ms)"); startTime = currentTime; } }
// This is a part of the saved state long startTime = System.currentTimeMillis(); for(int counter: IntStream.range(1, 10000).toArray()) { Thread.sleep(1000); long currentTime = System.currentTimeMillis(); System.out.println("Counter: " + counter + "(passed " + (currentTime-startTime) + " ms)"); startTime = currentTime; } }
args[]) throws InterruptedException { // This is a part of the saved state for(int counter: IntStream.range(1, 10000).toArray()) { Thread.sleep(1000); long currentTime = System.currentTimeMillis(); System.out.println("Counter: " + counter + "(passed " + (currentTime-startTime) + " ms)"); startTime = currentTime; } }
main(String args[]) throws InterruptedException { // This is a part of the saved state long startTime = System.currentTimeMillis(); Thread.sleep(1000); long currentTime = System.currentTimeMillis(); System.out.println("Counter: " + counter + "(passed " + (currentTime-startTime) + " ms)"); startTime = currentTime; } }
counter + "(passed " + (currentTime-startTime) + " ms)"); public static void main(String args[]) throws InterruptedException { // This is a part of the saved state long startTime = System.currentTimeMillis(); for(int counter: IntStream.range(1, 10000).toArray()) { startTime = currentTime; } }
throws InterruptedException { // This is a part of the saved state long startTime = System.currentTimeMillis(); for(int counter: IntStream.range(1, 10000).toArray()) { Thread.sleep(1000); long currentTime = System.currentTimeMillis(); System.out.println("Counter: " + counter + "(passed " + (currentTime-startTime) + " ms)"); } }
to access the whole process tree transfer data to or from the memory of arbitrary processes using process_vm_readv(2) and process_vm_writev(2) docker build -t pre_crack -f crac2/Dockerfile crac2 docker run --cap-add CAP_SYS_PTRACE --cap-add CAP_CHECKPOINT_RESTORE -d pre_crack # Not so frightening if you think about it
to access the whole process tree transfer data to or from the memory of arbitrary processes using process_vm_readv(2) and process_vm_writev(2) CAP_CHECKPOINT_RESTORE : somehow there is a special cap for this Update /proc/sys/kernel/ns_last_pid ; Read the contents of the symbolic links in /proc/pid/map_files for other processes docker build -t pre_crack -f crac2/Dockerfile crac2 docker run --cap-add CAP_SYS_PTRACE --cap-add CAP_CHECKPOINT_RESTORE -d pre_crack # Not so frightening if you think about it
public MongoClientProxy(MongoClient initialClient) { this.delegate = initialClient; } public class MongoClientProxy implements MongoClient { public void close() { delegate.close(); } // Delegate everything else the same way
{ delegate.close(); } public class MongoClientProxy implements MongoClient { volatile MongoClient delegate; public MongoClientProxy(MongoClient initialClient) { this.delegate = initialClient; } // Delegate everything else the same way
else the same way public class MongoClientProxy implements MongoClient { volatile MongoClient delegate; public MongoClientProxy(MongoClient initialClient) { this.delegate = initialClient; } public void close() { delegate.close(); }
→ Project Leyden EA builds to prepare to use it in the future 🎒 → Native Image for fast start ✊🏼 → CRaC for almost instant start Testing locally? Use a power cord! Which hero are you?