此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Boot 3.4.3! |
开发您的第一个 GraalVM 原生应用
构建 Spring Boot 本机映像应用程序有两种主要方法:
-
将 Spring Boot 对云原生 Buildpacks 的支持与 Paketo Java Native Image buildpack 结合使用,以生成包含本机可执行文件的轻量级容器。
-
使用 GraalVM Native Build Tools 生成原生可执行文件。
启动新的原生 Spring Boot 项目的最简单方法是转到 start.spring.io,添加GraalVM Native Support dependency 并生成项目。
包含HELP.md 文件将提供入门提示。 |
示例应用程序
我们需要一个示例应用程序,我们可以使用它来创建我们的原生镜像。 就我们的目的而言,开发您的第一个 Spring Boot 应用程序中介绍的简单 “Hello World!” Web 应用程序就足够了。
概括地说,我们的主要应用程序代码如下所示:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SpringBootApplication
public class MyApplication {
@RequestMapping("/")
String home() {
return "Hello World!";
}
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
This application uses Spring MVC and embedded Tomcat, both of which have been tested and verified to work with GraalVM native images.
Building a Native Image Using Buildpacks
Spring Boot supports building Docker images containing native executables, using Cloud Native Buildpacks (CNB) integration with both Maven and Gradle and the Paketo Java Native Image buildpack.
This means you can just type a single command and quickly get a sensible image into your locally running Docker daemon.
The resulting image doesn’t contain a JVM, instead the native image is compiled statically.
This leads to smaller images.
The CNB builder used for the images is paketobuildpacks/builder-jammy-java-tiny:latest
.
It has a small footprint and reduced attack surface. It does not include a shell and contains a reduced set of system libraries.
Use paketobuildpacks/builder-jammy-base:latest
or paketobuildpacks/builder-jammy-full:latest
to have more tools available in the image if required.
System Requirements
Docker should be installed. See Get Docker for more details.
Configure it to allow non-root user if you are on Linux.
You can run docker run hello-world
(without sudo
) to check the Docker daemon is reachable as expected.
Check the Maven or Gradle Spring Boot plugin documentation for more details.
On macOS, it is recommended to increase the memory allocated to Docker to at least 8GB
, and potentially add more CPUs as well.
See this Stack Overflow answer for more details.
On Microsoft Windows, make sure to enable the Docker WSL 2 backend for better performance.
Using Maven
To build a native image container using Maven you should ensure that your pom.xml
file uses the spring-boot-starter-parent
and the org.graalvm.buildtools:native-maven-plugin
.
You should have a <parent>
section that looks like this:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.0-SNAPSHOT</version>
</parent>
You additionally should have this in the <build> <plugins>
section:
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
</plugin>
The spring-boot-starter-parent
declares a native
profile that configures the executions that need to run in order to create a native image.
You can activate profiles using the -P
flag on the command line.
If you don’t want to use spring-boot-starter-parent
you’ll need to configure executions for the process-aot
goal from Spring Boot’s plugin and the add-reachability-metadata
goal from the Native Build Tools plugin.
To build the image, you can run the spring-boot:build-image
goal with the native
profile active:
$ mvn -Pnative spring-boot:build-image
Using Gradle
The Spring Boot Gradle plugin automatically configures AOT tasks when the GraalVM Native Image plugin is applied.
You should check that your Gradle build contains a plugins
block that includes org.graalvm.buildtools.native
.
As long as the org.graalvm.buildtools.native
plugin is applied, the bootBuildImage
task will generate a native image rather than a JVM one.
You can run the task using:
$ gradle bootBuildImage
Running the example
Once you have run the appropriate build command, a Docker image should be available.
You can start your application using docker run
:
$ docker run --rm -p 8080:8080 docker.io/library/myproject:0.0.1-SNAPSHOT
You should see output similar to the following:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v{version-spring-boot})
....... . . .
....... . . . (log output here)
....... . . .
........ Started MyApplication in 0.08 seconds (process running for 0.095)
The startup time differs from machine to machine, but it should be much faster than a Spring Boot application running on a JVM.
If you open a web browser to localhost:8080
, you should see the following output:
Hello World!
To gracefully exit the application, press ctrl-c
.
Building a Native Image using Native Build Tools
If you want to generate a native executable directly without using Docker, you can use GraalVM Native Build Tools.
Native Build Tools are plugins shipped by GraalVM for both Maven and Gradle.
You can use them to perform a variety of GraalVM tasks, including generating a native image.
Prerequisites
To build a native image using the Native Build Tools, you’ll need a GraalVM distribution on your machine.
You can either download it manually on the Liberica Native Image Kit page, or you can use a download manager like SDKMAN!.
Linux and macOS
To install the native image compiler on macOS or Linux, we recommend using SDKMAN!.
Get SDKMAN! from sdkman.io and install the Liberica GraalVM distribution by using the following commands:
$ sdk install java 22.3.r17-nik
$ sdk use java 22.3.r17-nik
Verify that the correct version has been configured by checking the output of java -version
:
$ java -version
openjdk version "17.0.5" 2022-10-18 LTS
OpenJDK Runtime Environment GraalVM 22.3.0 (build 17.0.5+8-LTS)
OpenJDK 64-Bit Server VM GraalVM 22.3.0 (build 17.0.5+8-LTS, mixed mode)
Windows
On Windows, follow these instructions to install either GraalVM or Liberica Native Image Kit in version 22.3, the Visual Studio Build Tools and the Windows SDK.
Due to the Windows related command-line maximum length, make sure to use x64 Native Tools Command Prompt instead of the regular Windows command line to run Maven or Gradle plugins.
Using Maven
As with the buildpacks support, you need to make sure that you’re using spring-boot-starter-parent
in order to inherit the native
profile and that the org.graalvm.buildtools:native-maven-plugin
plugin is used.
With the native
profile active, you can invoke the native:compile
goal to trigger native-image
compilation:
$ mvn -Pnative native:compile
The native image executable can be found in the target
directory.
Using Gradle
When the Native Build Tools Gradle plugin is applied to your project, the Spring Boot Gradle plugin will automatically trigger the Spring AOT engine.
Task dependencies are automatically configured, so you can just run the standard nativeCompile
task to generate a native image:
$ gradle nativeCompile
The native image executable can be found in the build/native/nativeCompile
directory.
Running the Example
At this point, your application should work. You can now start the application by running it directly:
-
Maven
-
Gradle
$ target/myproject
$ build/native/nativeCompile/myproject
You should see output similar to the following:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.5.0-SNAPSHOT)
....... . . .
....... . . . (log output here)
....... . . .
........ Started MyApplication in 0.08 seconds (process running for 0.095)
The startup time differs from machine to machine, but it should be much faster than a Spring Boot application running on a JVM.
If you open a web browser to localhost:8080
, you should see the following output:
Hello World!
To gracefully exit the application, press ctrl-c
.