Compile a Spring Boot Infinispan Application to a GraalVM Native Image
What You Will Learn
How to compile a Spring Boot application that uses the Infinispan Hot Rod client into a GraalVM native image. The resulting native executable starts in milliseconds and uses a fraction of the memory compared to the JVM.
This tutorial builds on the Spring Boot Automatic Protobuf Schema Registration tutorial and adds the configuration needed for GraalVM native image compilation.
Prerequisites
-
Java 21+ with GraalVM (for native compilation)
-
Maven 3.6+
-
Docker or Podman (for running Infinispan Server)
Step 1: Start an Infinispan Server
Start an Infinispan Server using Docker or Podman:
docker run -it --rm -p 11222:11222 -e USER=admin -e PASS=password quay.io/infinispan/server:latest
|
Tip
|
You can replace docker with podman in the command above if you use Podman.
|
Step 2: Add Dependencies
In addition to the standard Spring Boot Infinispan starter, add the GraalVM native image metadata module:
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-spring-boot4-starter-remote</artifactId>
</dependency>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-client-hotrod-graalvm</artifactId>
</dependency>
<dependency>
<groupId>org.infinispan.protostream</groupId>
<artifactId>protostream-processor</artifactId>
</dependency>
The infinispan-client-hotrod-graalvm artifact provides META-INF/native-image/ metadata that registers the reflection entries and resource includes needed by the Hot Rod client at native image build time.
Step 3: Define Protobuf Entities and Schema
Define your Protobuf entities and schema exactly as you would for a JVM application:
@Proto
@Indexed
public record Character(UUID id, @Text String name, @Text String bio, Archetype archetype) {
}
@ProtoSchema(schemaPackageName = "tutorial",
includeClasses = {Character.class, Archetype.class},
dependsOn = {
org.infinispan.protostream.types.java.CommonTypes.class
})
public interface AppSchema extends GeneratedSchema {
}
Step 4: Register the Schema Bean for Native Mode
The Infinispan Spring Boot starter normally discovers GeneratedSchema implementations by scanning the classpath at runtime.
This classpath scanning does not work in a native image because all classes are compiled ahead-of-time into the binary.
To work around this, explicitly register the generated schema implementation as a Spring bean:
@Configuration
@ImportRuntimeHints(NativeConfiguration.InfinispanRuntimeHints.class)
public class NativeConfiguration {
@Bean
GeneratedSchema appSchema() {
return new AppSchemaImpl();
}
static class InfinispanRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
hints.resources().registerPattern("*.csv");
}
}
}
Key points:
-
The
@Beanmethod returns the annotation-processor-generatedAppSchemaImpl. The starter’s auto-configuration picks it up via dependency injection and registers it with theRemoteCacheManager. -
The
RuntimeHintsRegistrarensures that application-specific resource files loaded at runtime (such as the CSV data file) are included in the native image.
Step 5: Configure the Native Maven Profile
Since this project does not use spring-boot-starter-parent as its Maven parent, the native build profile must be configured manually.
Add the following profile to your pom.xml:
<profiles>
<profile>
<id>native</id>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>process-aot</id>
<goals>
<goal>process-aot</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<id>add-reachability-metadata</id>
<goals>
<goal>add-reachability-metadata</goal>
</goals>
</execution>
</executions>
<configuration>
<buildArgs>
<buildArg>-H:+AddAllCharsets</buildArg>
</buildArgs>
<fallback>false</fallback>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
This profile configures:
-
Spring Boot AOT processing (
process-aot): pre-computes dependency injection, auto-configuration, and@ConfigurationPropertiesbindings at build time, eliminating the need for reflection at runtime. -
GraalVM Native Maven Plugin: compiles the AOT-processed application into a native executable. The
add-reachability-metadatagoal downloads third-party native image metadata from the GraalVM reachability metadata repository. -
-H:+AddAllCharsets: includes all character set support, required by the Infinispan client for certain encoding operations. -
fallback=false: ensures a true native image is built; the build fails rather than silently falling back to a JVM-based executable.
Step 6: Build and Run in JVM Mode
First verify that the application works on the JVM:
mvn spring-boot:run
Then test the REST endpoints:
curl http://localhost:8080/characters/0
curl "http://localhost:8080/characters/query?term=Felix"
Step 7: Build the Native Image
Build the native executable using the native profile:
mvn -Pnative native:compile
|
Note
|
Native image compilation requires significantly more time and memory than a regular build. Expect 2-5 minutes depending on your machine. Ensure at least 4GB of RAM is available for the build process. |
Step 8: Run the Native Executable
Run the compiled native executable:
./target/infinispan-spring-boot-native-cache-remote
You should see the application start in well under a second. The same REST endpoints are available:
curl http://localhost:8080/characters/0
curl "http://localhost:8080/characters/query?term=Felix"
How It Works
Three layers work together to make the native image functional:
| Layer | What it covers |
|---|---|
Spring Boot AOT ( |
All Spring annotations, dependency injection wiring, |
|
Hot Rod client internals: SASL authentication providers (Elytron), consistent hashing, event listeners, ProtoStream |
|
Application-specific: |
What’s Next
-
Spring Boot Automatic Protobuf Schema Registration for the JVM-only version of this tutorial
-
Quarkus Infinispan Client for the same pattern with Quarkus


