Back

Build a Native Executable from a Spring Boot Application

GraalVM Native Image can significantly boost the performance of a Spring Boot application. Spring Boot 3 has integrated support for GraalVM Native Image, making it easier to set up and configure your project.

This guide demonstrates how to build a native executable from a Spring Boot 3 application.

Create an Application

For the demo part, you will create a simple REST server Java application.

  1. Go to Spring Initializr and create a new Spring Boot project. Ensure to add the GraalVM Native Support and Spring Web dependencies.

  2. Click GENERATE to create and download the project as a .zip file. Unzip the file and open it in your favorite IDE.

    The project configuration already contains all necessary dependencies and plugins, including Native Build Tools. For example, if you created a Maven project, these are the required plugins added in the pom.xml file:

     <build>
         <plugins>
             <plugin>
                 <groupId>org.graalvm.buildtools</groupId>
                 <artifactId>native-maven-plugin</artifactId>
             </plugin>
             <plugin>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
             </plugin>
         </plugins>
     </build>
    
  3. The main application class was created by the initializer. In the same directory, create a REST controller in a file named HelloController.java with the following contents:
     package com.example.demo;
    
     import org.springframework.web.bind.annotation.GetMapping;
     import org.springframework.web.bind.annotation.RestController;
    
     @RestController
     public class HelloController {
    
         @GetMapping("/hello")
         public String hello() {
             return "Hello, GraalVM!";
         }
     }
    
  4. (Optional) Package and run the application on a Java HotSpot Virtual Machine.
    Maven:
     ./mvnw spring-boot:run
    

    Gradle:

     ./gradlew bootRun
    

    It compiles the application, creates a JAR file, and runs the application.

    The application starts in hundreds of milliseconds. Open a browser and navigate to localhost:8080/hello to see the application running. You should see “Hello, GraalVM!”.

Build a Native Executable Using Paketo Buildpacks

Spring Boot supports building container images containing native executables using the Paketo Buildpack for Oracle which provides GraalVM Native Image.

Prerequisite

Make sure you have a Docker-API compatible container runtime such as Rancher Desktop or Docker installed and running.

  1. First, enable the Paketo Buildpack for Oracle requesting the Native Image tool.

    • Maven. Open the pom.xml file, find the spring-boot-maven-plugin declaration, and change it so that it looks like this:
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <image>
                    <builder>paketobuildpacks/builder-jammy-buildpackless-tiny</builder><!--required for AArch64/M1 support -->
                    <buildpacks>
                        <buildpack>paketobuildpacks/oracle</buildpack>
                        <buildpack>paketobuildpacks/java-native-image</buildpack>
                    </buildpacks>
                </image>
            </configuration>
        </plugin>
      

      You should also ensure that your pom.xml file uses spring-boot-starter-parent. The <parent> section should have been added by the initializer.

    • Gradle. Open the build.gradle file, and add the following lines:
        bootBuildImage {
                builder = "paketobuildpacks/builder-jammy-buildpackless-tiny"
                buildpacks = ["paketobuildpacks/oracle", "paketobuildpacks/java-native-image"]
        }
      

      When java-native-image is requested, the buildpack downloads Oracle GraalVM, which includes Native Image.

  2. Build a native executable for this Spring application using buildpacks:
    • Maven:
        ./mvnw -Pnative spring-boot:build-image
      
    • Gradle:
        ./gradlew bootBuildImage
      
  3. Once the build completes, a Docker image should be available. You can start your application using docker run. For example:
     docker run --rm -p 8080:8080 docker.io/library/demo:0.0.1-SNAPSHOT
    

The Paketo documentation provides several examples that show you how to build applications with GraalVM Native Image using buildpacks.

Build a Native Executable Using Native Build Tools

If you do not want to use Docker and create a native executable on a host machine, use Native Build Tools which provide Maven and Gradle plugins for building native images.

Prerequisite

Make sure you have installed a GraalVM JDK. The easiest way to get started is with SDKMAN!:

sdk install java 21.0.4-graal

Substitute 21.0.4 with a preferred GraalVM release or early access build. For other installation options, visit the Downloads section.

  1. Build a native executable using Native Build Tools:
    • Maven:
        ./mvnw -Pnative native:compile
      

      The command compiles the project and creates a native executable, demo, in the target/ directory.

    • Gradle:
        ./gradlew nativeCompile
      

      The command compiles the project and creates a native executable, demo, in the build/native/nativeCompile/ directory.

  2. Run the application from the native executable:
    • Maven:
        ./target/demo
      
    • Gradle:
        ./build/native/nativeCompile/demo
      

      With Gradle, you can also execute the nativeRun task: gradle nativeRun.

      If you ran this application on HotSpot before, you would notice that startup time decreased significantly.

This guide demonstrated how you can create a native executable for a Spring Boot application. You can do that in a container environment using Paketo Buildpacks, or on a host machine using Native Build Tools.

A Spring Boot application when compiled ahead of time into a native executable is not only faster and lighter, but also more efficient, especially in environments with constrained resources such as cloud platforms or containers.

Connect with us