Documentation

Documentation versions (currently viewingVaadin 24)

Native Image Compilation with GraalVM

Compiling a Vaadin Flow application into a native image using GraalVM.

For Spring Boot-based applications, Vaadin supports native image compilation with GraalVM. By compiling your application into a native image, you can benefit from much faster startup times (milliseconds) and lower memory consumption compared to running the application on the JVM.

Requirements

Before you begin, ensure you have a JDK with GraalVM support.

To check whether you have a JDK with GraalVM support, execute the java -version command in your terminal.

java -version

If the output contains the following text, you have a JDK with GraalVM support installed:

GraalVM

If not, you can install one by following the instructions in the Install GraalVM section of the GraalVM documentation or by using the SDKMAN tool.

Using Reflection in an Application

It’s a two-step process to compile a Java application to a native binary. First, there’s an ahead-of-time (AOT) stage in which the Java application is run to determine what resources it will use. The next step is the actual compilation based on what was determined in the first step. In some cases, the compiler is not able to determine in the AOT stage all of the needed classes and resources. In which case, you’ll need to provide hints of what’s needed.

For instance, Grid uses reflection to determine which fields a class has to create columns. This won’t work in a native image, unless you include an annotation to tell the compiler you need reflection information for the classes it uses. You can provide those details, those hints by adding a [@RegisterReflectionForBinding](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aot/hint/annotation/RegisterReflectionForBinding.html) annotation.

@Route("")
@RegisterReflectionForBinding({Person.class})
public class PersonView extends VerticalLayout {

    public PersonView() {
        var grid = new Grid<>(Person.class);
        grid.setItems(List.of(
            new Person("John Doe", "john@doe.com"),
            new Person("Jane Doe", "jane@doe.com")
        ));

        add(grid);
    }
}

With the annotation, it works as expected. Without it, you would get an empty grid in a natively compiled application. You can have the annotation either on a class or on a method, but not on the constructor.

Compilation

Compile your Vaadin application into a native image using Maven by executing the following command in the project root directory:

mvn -Pproduction -Pnative native:compile

This command compiles the application with the production and native profiles enabled. The native profile instructs Maven to use the GraalVM native image compiler for the compilation process.

Now run the application. The compilation creates the native image in the target directory. To run it, execute the following command:

./target/<app-name>

Your Vaadin application is now running as a native image, benefiting from faster startup times and lower memory consumption.

More Resources

For more information on native image compilation and instructions on creating Docker images using build packs, see the Spring Boot Reference Guide.