GraalVM
Introduction
GraalVM is a new virtual machine that supports a polyglot runtime environment and the ability to compile Java applications to native images.
RESTHeart fully supports the GraalVM:
- RESTHeart can be run and is supported on the GraalVM
- Services and Interceptors can be implemented in JavaScript and TypeScript leveraging the GraalVM polyglot programming model
- RESTHeart (and your custom plugins) can be built as a native image using GraalVM’s
native-image
tool
Why GraalVM
GraalVM provides advanced optimizing compiler that generates fast lean code which requires fewer compute resources and allows Ahead-of-Time Compilation to build Native binaries that start up instantly and deliver peak performance with no warm up time.
Images from graalvm.org website.
Benefits of running RESTHeart with the GraalVM
The GraalVM is faster than OpenJDK and it is also a polyglot runtime environment, so that you can seamlessly use multiple languages to implement RESTHeart plugins.
RESTHeart leverages the GraalVM to allow developing services and interceptors using JavaScript.
See Polyglot JavaScript Services and Interceptors for more details.
Want to see some code? Several code examples are available as well.
Benefits of running RESTHeart as a native image
Building a RESTHeart application to native image provides multiple advantages, including faster startup time and smaller memory footprint.
A RESTHeart application is a bundle of RESTHeart core and plugins. The plugins can include the one shipped with RESTHeart (restheart-mongodb.jar
and restheart-security.jar
) and custom plugins that implement your application logic.
The following table compares RESTHeart (with default plugins) running on a MacBook Pro with OpenJDK, GraalVM CE and GraalVM CE native image.
OpenJDK | GraalVM CE | GraalVM CE native | |
---|---|---|---|
startup time | 2441ms | 2042ms | 249ms |
memory | 487Mbyte | 761Mbyte | 279Mbyte |
integration test execution time | 63,503s | 57,292s | 52,518s |
The numbers clearly show that running RESTHeart as a native image is ideal for microservices and clustering. With instant startup time and smaller memory footprint you can run multiple instances of RESTHeart Docker images and also better support dynamic scaling.
In some use cases, native image might result in slightly worse peak performance. Read this great article for more information. The fact that peak performances might be worse, is well compensated by the ability to run more RESTHeart instances in parallel due to much smaller memory footprint.
Install the GraalVM
We suggest to install GraalVM with sdkman
You need at least version 23.1.2 for Java 21:
$ sdk install java 21.0.2-graalce
Run RESTHeart with GraalVM
Check that GraalVM SDK is active:
$ java -version
openjdk version "21.0.2" 2024-01-16
OpenJDK Runtime Environment GraalVM CE 21.0.2+13.1 (build 21.0.2+13-jvmci-23.1-b30)
OpenJDK 64-Bit Server VM GraalVM CE 21.0.2+13.1 (build 21.0.2+13-jvmci-23.1-b30, mixed mode, sharing)
Then just run RESTHeart as usual:
$ java -jar restheart.jar etc/restheart.yml -e etc/default.properties
Build stock RESTHeart as native image
A Docker image of RESTHeart native is available tagged as softinstigate/restheart:<version>-native
Example:
$ docker pull softinstigate/restheart:latest-native
The docker-compose-native.yml leveraging restheart-native is available as well. It runs restheart-native and MongoDB stack.
how to build from source
RESTHeart’s pom.xml
includes the native
profile.
Check that GraalVM SDK is active:
$ java -version
openjdk version "21.0.2" 2024-01-16
OpenJDK Runtime Environment GraalVM CE 21.0.2+13.1 (build 21.0.2+13-jvmci-23.1-b30)
OpenJDK 64-Bit Server VM GraalVM CE 21.0.2+13.1 (build 21.0.2+13-jvmci-23.1-b30, mixed mode, sharing)
You can then simply build it with:
$ git checkout https://github.com/SoftInstigate/restheart.git
$ cd restheart
$ ./mvnw clean package -Pnative
As a result, you’ll find the executable binary file target/restheart-native
.
Build RESTHeart with custom plugins as native image
JavaScript plugins can be deployed on RESTHeart native. However you cannot deploy Java plugins in RESTHeart native by merely copying jars file into the plugins directory.
In order to use Java or Kotlin plugins on RESTHeart native you must build them as native image together with RESTHeart.
Refer to Deploy Java Plugins On Restheart Native for detailed instructions on how to do it.
build native image
Build image for local OS
$ ./mvnw clean package -Pnative -DskipTests
A docker image to build Linux native images
SoftInstigate maintains the Debian based, docker image softinstigate/graalvm-maven with GraalVM and Maven and native-image
.
Use it if you are running a different OS and you need to build a native image for Linux to include it in a Docker image.
$ docker pull softinstigate/graalvm-maven
You can build a Linux native image with:
$ docker run -it --rm \
-v "$PWD":/opt/app \
-v "$HOME"/.m2:/root/.m2 \
softinstigate/graalvm-maven \
clean package -Pnative -DskipTests
native-image arguments are defined in this file.