Skip to content

Spring Boot with GraalVM

Moritz Halbritter edited this page Jan 10, 2023 · 52 revisions

Known GraalVM Native Image limitations

General

Core container

  • Using beans defined as lambdas or instance suppliers with AOT/native is not yet supported. You can track the related issue spring-framework#29555 where some workarounds are described.

Testing

  • Mockito is not supported yet, see #32195. You can disable tests which rely on Mockito with @DisabledInNativeImage.

Building Container Images

WebJars

  • WebJars are not recommended with native images since the webjars-locator-core dependency involves unsupported resource scanning at runtime, and since WebJars dependencies lead to the inclusion of unneeded resources from META-INF/resources/. Consider alternative approaches like directly shipping the required frontend resources in the web application, potentially by leveraging build plugins like the gradle-node-plugin for Gradle or the frontend-maven-plugin for Maven (see related blog post).

SQL

In-Memory Databases

HSQLDB is not supported in a native image. If you require an in-memory database, please use H2 instead.

Flyway

Automatic detection of Java migrations are not supported in native image, see #33458

Hibernate

Gradle projects written in Kotlin will fail with a ClassCastException when attempting to configure Hibernate’s bytecode enhancement. HHH-15707 is tracking the problem.

Native libraries needed on Linux / MacOS systems

If org.glassfish.jaxb:jaxb-runtime is used (for example, JPA / Hibernate depends on it), you’ll need to install the libfreetype library on your Linux or MacOS system. That’s because a class inside JAXB depends on javax.imageio, which will initialize the graphics subsystem.

Spring Web Services

Spring-WS does not support AOT and GraalVM Native at the moment.

Spring Cloud

Further GraalVM tweaking

Using tomcat-embed-programmatic

Motivation

tomcat-embed-programmatic is an experimental Tomcat dependency designed to lower the memory footprint. Using it produces smaller native images.

Maven

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <exclusions>
    <exclusion>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-core</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-websocket</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>org.apache.tomcat.experimental</groupId>
  <artifactId>tomcat-embed-programmatic</artifactId>
  <version>${tomcat.version}</version>
</dependency>

Gradle

implementation('org.springframework.boot:spring-boot-starter-web') {
  exclude group: 'org.apache.tomcat.embed', module: 'tomcat-embed-core'
  exclude group: 'org.apache.tomcat.embed', module: 'tomcat-embed-websocket'
}
String tomcatVersion = dependencyManagement.importedProperties['tomcat.version']
implementation "org.apache.tomcat.experimental:tomcat-embed-programmatic:$tomcatVersion"
Clone this wiki locally