Backend Development 12 min read

How to Turn a Java Hello World into a Fast Native Binary with GraalVM

This article walks through writing a simple Java program, compiling it with javac, then using GraalVM's native-image tool to produce a JVM‑independent executable, compares file size and startup speed, discusses native-image limitations, and shows how Spring Boot can be built as a native image for dramatically faster startup.

macrozheng
macrozheng
macrozheng
How to Turn a Java Hello World into a Fast Native Binary with GraalVM

Write a simple Java program and compile it with

javac

, then run it with

java

.

<code>public class Hello {
    public static void main(String[] args) {
        System.out.println("hello world");
    }
}
</code>

Running the program requires a JRE.

Instead, use GraalVM's

native-image

tool to compile the program into a native executable.

<code>native-image Hello
</code>

After compilation, a binary file

hello

appears, which can be executed directly without a JRE.

<code>./hello
hello world
</code>

This demonstrates that

native-image

turns Java code into a JVM‑independent native binary.

GraalVM offers three main features:

New JIT technology for faster Java execution.

Polyglot language support.

Building JVM‑independent native images.

Using

native-image

reduces startup time dramatically but increases binary size. A comparison of

Hello.class

(415 B, 0.12 s) and the native

hello

(10 M, 0.01 s) shows the trade‑off.

For larger applications such as Spring Boot, native images can be built with Spring Native support. After generating a project from

start.spring.io

, the Maven command

mvn package -Pnative

produces a native executable.

<code># native image build output (truncated)
[INFO] Executing: ...native-image -cp ... -H:Name=demo-1
... (build logs) ...
</code>

Running the traditional JAR takes about 2 seconds to start, while the native executable starts in 0.078 seconds.

Native compilation has limitations: it does not support dynamic class loading, reflection, serialization, JNI, etc., unless explicit configuration is provided. These constraints stem from the AOT (ahead‑of‑time) compilation model, which assumes a closed world at build time.

Spring Native mitigates this by supplying the necessary configuration for common frameworks, allowing developers to build fast‑starting native Spring Boot applications.

Overall, GraalVM

native-image

can dramatically improve startup latency, especially for cloud‑native workloads, though binary size and configuration complexity must be considered.

GraalVM native-image example
GraalVM native-image example
JavaperformanceSpring BootGraalVMnative-imageAOT compilation
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.