Cloud Native 12 min read

How to Build Lightning‑Fast Spring Boot Apps with Spring Native and GraalVM

This tutorial walks through installing GraalVM, configuring Spring Native, building a native Spring Boot application using Buildpacks or the native‑image plugin, creating Docker containers, and comparing startup speed and memory usage against traditional Java execution, providing full pom.xml examples and official documentation links.

Java High-Performance Architecture
Java High-Performance Architecture
Java High-Performance Architecture
How to Build Lightning‑Fast Spring Boot Apps with Spring Native and GraalVM

What is Spring Native

Spring Native provides beta support for compiling Spring applications into native executables using the GraalVM native‑image compiler, enabling lightweight container deployment and near‑millisecond startup times.

Environment Setup

OS: Windows10 21H2
IDE: IntelliJ IDEA 2022.1.3
JDK: graalvm-ce-java11-22.2.0
Maven: 3.5.4
Docker Desktop for Windows: 4.12.0
Spring Boot: 2.7.4
Spring Native: 0.12.1

Building a Native Spring Boot Application

Two main approaches:

Use Spring Boot Buildpacks to generate a container that includes the native executable.

Use the GraalVM native‑image Maven plugin to produce a native executable directly.

Method 1 – Buildpacks

Since Spring Boot 2.3 you can use the spring-boot-maven-plugin with the spring-boot:build-image goal. The plugin builds a Docker image without requiring a Dockerfile; configuration is placed in pom.xml under the configuration element.

Method 2 – Native‑image Plugin

This method does not need Docker but requires Visual Studio with the MSVC toolchain. Run mvn -Pnative package to generate an executable (.exe).

Key Differences

Method 1 requires Docker; Method 2 requires Visual Studio.

The Maven commands differ: mvn spring-boot:build-image vs mvn -Pnative package.

For Docker‑based microservices, Method 1 is typically preferred.

Installing GraalVM

https://www.graalvm.org/downloads/

Configuring Environment Variables

Verify the installation with gu install native-image.

Installing Docker Desktop for Windows

https://docs.docker.com/desktop/windows/install/

Creating a Spring Boot Project

Full pom.xml example:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.4</version>
    <relativePath/>
  </parent>
  <groupId>com.example</groupId>
  <artifactId>spring-native</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <properties>
    <java.version>11</java.version>
    <spring-native.version>0.12.1</spring-native.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.experimental</groupId>
      <artifactId>spring-native</artifactId>
      <version>${spring-native.version}</version>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <excludes>
            <exclude>
              <groupId>org.projectlombok</groupId>
              <artifactId>lombok</artifactId>
            </exclude>
          </excludes>
          <classifier>${repackage.classifier}</classifier>
          <image>
            <builder>paketobuildpacks/builder:tiny</builder>
            <env>
              <BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
              <BPE_APPEND_JAVA_TOOL_OPTIONS>-Xms128m</BPE_APPEND_JAVA_TOOL_OPTIONS>
              <BPE_APPEND_JAVA_TOOL_OPTIONS>-Xmx128m</BPE_APPEND_JAVA_TOOL_OPTIONS>
              <BPE_APPEND_JAVA_TOOL_OPTIONS>-Xss256k</BPE_APPEND_JAVA_TOOL_OPTIONS>
              <BPE_APPEND_JAVA_TOOL_OPTIONS>-XX:ParallelGCThreads=2</BPE_APPEND_JAVA_TOOL_OPTIONS>
              <BPE_APPEND_JAVA_TOOL_OPTIONS>-XX:+PrintGCDetails</BPE_APPEND_JAVA_TOOL_OPTIONS>
            </env>
          </image>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.springframework.experimental</groupId>
        <artifactId>spring-aot-maven-plugin</artifactId>
        <version>${spring-native.version}</version>
        <executions>
          <execution>
            <id>test-generate</id>
            <goals>
              <goal>test-generate</goal>
            </goals>
          </execution>
          <execution>
            <id>generate</id>
            <goals>
              <goal>generate</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  <repositories>
    <repository>
      <id>spring-releases</id>
      <name>Spring Releases</name>
      <url>https://repo.spring.io/release</url>
      <snapshots><enabled>false</enabled></snapshots>
    </repository>
  </repositories>
  <pluginRepositories>
    <pluginRepository>
      <id>spring-releases</id>
      <name>Spring Releases</name>
      <url>https://repo.spring.io/release</url>
      <snapshots><enabled>false</enabled></snapshots>
    </pluginRepository>
  </pluginRepositories>
</project>

The article uses Spring Native 0.12.1, which requires Spring Boot 2.7.4. Additional parameters such as Docker registry, JVM options, and certificates can be configured under the

spring-boot-maven-plugin
configuration

element.

Building and Running

Execute:

mvn clean
mvn '-Dmaven.test.skip=true' spring-boot:build-image

The build downloads dependencies, compiles the project, and creates a Docker image named spring-native. CPU and memory usage are high during compilation, and build time varies with hardware and network conditions.

Creating and Running the Container

List images: docker images Run the container:

docker run -id -p 8888:8888 --name=native-app spring-native:0.0.1-SNAPSHOT

Docker Desktop shows the application starts in approximately 31 ms and consumes about 46 MiB of memory.

Comparison with Traditional Startup

Starting the same application with java -jar takes roughly 1.5 seconds and uses around 238 MiB of memory.

Further Reading

https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/index.html
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaDockerSpring BootGraalVMnative-imageSpring Nativebuildpacks
Java High-Performance Architecture
Written by

Java High-Performance Architecture

Sharing Java development articles and resources, including SSM architecture and the Spring ecosystem (Spring Boot, Spring Cloud, MyBatis, Dubbo, Docker), Zookeeper, Redis, architecture design, microservices, message queues, Git, etc.

0 followers
Reader feedback

How this landed with the community

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.