This project goal is to provide experimental support for building Spring Boot applications as GraalVM native images. Read this blog post or watch this Running Spring Boot applications as GraalVM native images Devoxx talk video for more details.
It is mainly composed of 6 parts:
-
spring-graalvm-native-feature
: this module is Spring GraalVM feature. A feature here is a GraalVM term meaning a plugin for the native-image compilation process (which creates the native-image from the built class files). The feature participates in the compilation lifecycle, being invoked at different compilation stages to offer extra information about the application to aid in the image construction. -
spring-graalvm-native-configuration
: this module contains configuration hints for Spring classes, including various Spring Boot auto-configurations. -
spring-graalvm-native-substitutions
: this module allows to patch temporarily some part of Spring Boot and Spring Framework to improve compatibility and efficiency of Spring native images. -
spring-graalvm-native
: this module aggregates the feature, configuration and substitutions ones to generate the artifact to consume. -
spring-graalvm-native-samples
: contains various samples that demonstrate the feature usage and are used as integration tests. -
spring-graalvm-native-docs
: contains the asciidoc documentation sources.
It supports the following modes using -Dspring.native.mode=<mode>
on the native-image
command line:
-
default
provides resource, initialization, proxy and reflection (using auto-configuration hints) configuration for native images as well as substitutions. -
agent
should be used if only wishing to provide initialization configuration and substitutions. -
hybrid
is a work-in-progress mode which is a mix between the 2 previous modes. The agent is used for Spring Boot auto-configuration and the feature and hints are used for user beans like@Controller
. -
functional
is when working with functional bean registration (Spring Fu style or using spring-init). In this mode the feature will provide initialization, resource configuration, substitutions andspring.factories
functional alternative (only Spring Bootspring.factories
are supported for now).
This project status is alpha, that means that we are currently mainly working on the software design and on supporting the features of the current samples (work in progress). Supporting a wider and clearly defined range of Spring Boot applications, as well as optimizing efficiency (image size, memory consumption) and performances will happen as a second step.
Spring team collaborates with GraalVM native team by raising issues in their bug tracker, with the goal to improve the production-readiness of native-images. These bugs on GraalVM issue tracker are identified by the spring
label.
For detailed information and walkthroughs of applying the techniques to your project, please see the documentation.
If you are using Docker based builds descried above, the right GraalVM distribution is already installed, you can skip this section.
From GraalVM builds:
Or you can use SDKMAN to easily switch between GraalVM versions:
-
Install GraalVM with
sdk install java 20.1.0.r8-grl
for Java 8 orsdk install java 20.1.0.r11-grl
for Java 11 -
Run
gu install native-image
to bring in the native-image extensions to the JDK.
The latest 0.7.1 release supports GraalVM 20.1.0 and Spring Boot 2.3.1.RELEASE.
-
Artifact:
org.springframework.experimental:spring-graalvm-native:0.7.1
-
Repository:
https://repo.spring.io/milestone
-
Download and extract sources from the latest release.
-
Go into the samples folder and pick one (e.g.
cd spring-graalvm-native-samples/commandlinerunner
) -
Run
./build.sh
which will run a maven build, then a native image compile, then test the result.
build.sh
runs the compile.sh
script and in that compile script you can see the invocation of the native-image
command. The other samples follow a similar model. For more details on the samples see the samples documentation.
This project is in the spring-projects-experimental
org indicating it is not as mature as other Spring projects. Contributions are welcome (maybe read the extension guide if thinking about extending it to support your project). However, please recognize we aren’t at the polishing javadoc stage and whilst pre 1.0 there may be heavy evolution of APIs.
In order to allow easily reproducible builds of spring-graalvm-native
, dedicated interactive Docker images are available for local development (tested on Linux and Mac) and are also used in the CI:
-
graalvm-ce
: base image with Ubuntu bionic + GraalVM native, built daily by the CI and available from Docker hub or locally viadocker/build-graalvm-ce-images.sh
. -
spring-graalvm-native
: base image withgraalvm-ce
+ utilities required to build the project, available from Docker hub or locally viadocker/build-spring-graalvm-native-images.sh
. -
spring-graalvm-native-dev
: local image built viadocker/build-dev-images.sh
designed to share the same user between the host and the container
To use it:
-
Configure it to allow non-root user if you are on Linux.
-
Run
run-dev-container.sh
to run the Docker container with an interactive shell suitable to runspring-graalvm-native
build scripts (see bellow for more documentation). -
The first time, it will download remote based images built by the CI.
-
The current and the Maven home directories are shared between the host (where is typically the IDE) and the container (where you can run builds).
run-dev-container.sh
runs Spring GraalVM native dev container with an interactive shell.
run-dev-container.sh [options]
options:
-h, --help show brief help
-j, --java=VERSION specify Java version to use, can be 8 or 11, 8 by default
-g, --graalvm=VERSION specify GraalVM version to use, can be 20.1-dev or master, 20.1-dev by default
-w, --workdir specify the working directory, should be an absolute path, current one by default
-p, --pull force pulling of remote container images
-r, --rebuild force container image rebuild
-
Import the root project in your IDE.
-
Eventually import the sample you are working on as a distinct project in your IDE.
-
Run
run-dev-container.sh
to run the Docker container with an interactive shell. -
Run the root project
build.sh
(from the host or the container) if you have made modification to the feature, substitutions or configuration modules. -
Run
build.sh
of the sample you are working on from the container.
To test the various samples You can also run the root build.sh
then build-key-samples.sh
(test only key samples) or build-samples.sh
(test all samples) from the container.