Native desktop application using Substrate, GraalVM


Native applications are known for their fast startup time, high performance and low footprint. Think of a world where any Java application can be converted into a native application in minutes with almost no effort, leaving you with all the speed gains and no headache.

Gluon Substrate is a tool that converts Java(FX) applications into native executable for desktop, mobile and embedded devices. Gluon Substrate uses GraalVM native-image tool to compile the required Java byte-code into native code that can be executed on the target system:

 

 

For this blog post, we will simply create a native executable for desktop. Although Gluon Substrate has an API that allows direct access to it, the easiest and fastest way to use Gluon Substrate in an application is via the client plugins. We will use the client maven plugin in the following example. The plugin can be added to any Java application (using Maven), by adding the following block of code to its pom.xml:

<plugin>
    <groupid>com.gluonhq</groupid>
    <artifactid>client-maven-plugin</artifactid>
    <version>0.1.6</version>
    <configuration>
        <mainclass>your.mainClass</mainclass>
    </configuration>
</plugin>

<pluginrepositories>
    <pluginrepository>
        <id>gluon-releases</id>
        <url>https://nexus.gluonhq.com/nexus/content/repositories/releases/</url>
    </pluginrepository>
</pluginrepositories>

And that’s it! Gluon Substrate does all the work in the background by analyzing the project and its requirement, providing the required set of parameters to GraalVM native-image, and link it with the required libraries to create the perfect native image for your application.

Note: Gluon Substrate and GraalVM native-image detects classes for reflection. However, for complex applications it might still be required to specify a list of classes, as we will explain in a later post. We are continuously working on improving the tools and making it easier to create and run native executable.

To showcase how we can use Gluon Substrate on a real world application, let’s create a simple JavaFX application and convert it to native application.

Before we proceed any further, please make sure to have the following prerequisites:

  • GraalVM 19.3 or later – Download and unzip GraalVM for Java 11. Set GRAALVM_HOME to this directory
  • Set JAVA_HOME to either GRAALVM directory or any other JDK11 directory
  • Download and install Maven 3 or later

Once the above things are in place, we can continue creating our application. We will use a Maven archetype to quickly create the application.

mvn archetype:generate \
        -DarchetypeGroupId=com.gluonhq \
        -DarchetypeArtifactId=client-archetype-javafx \
        -DarchetypeVersion=0.0.1 \
        -DgroupId=hello \
        -DartifactId=hellofx \
        -Dversion=1.0-SNAPSHOT
The project created by this archetype is present in a Github repository for quick access.

The sample JavaFX application will show the current Java and JavaFX versions used to run the application, along with an image of Duke. The application will have only one class and a few resources.

public void start(Stage stage) {
    String javaVersion = System.getProperty("java.version");
    String javafxVersion = System.getProperty("javafx.version");
    Label label = new Label("Hello, JavaFX " + javafxVersion + 
                            ", running on Java " + javaVersion + ".");
    ImageView imageView = new ImageView("/hellofx/openduke.png");
    imageView.setFitHeight(200);
    imageView.setPreserveRatio(true);
    VBox root = new VBox(30, imageView, label);
    root.setAlignment(Pos.CENTER);
    Scene scene = new Scene(root, 640, 480);
    scene.getStylesheets().add(getClass().getResource("styles.css").toExternalForm());
    stage.setScene(scene);
    stage.show();
}

We will use the javafx-maven-plugin to run the application before converting it to a native image. Run the application using the following command:

mvn javafx:run

A stage shows up with an image of Duke along with the current Java and JavaFX details:

Now that the application is ready, we can convert it to native image using Gluon Substrate. Maven plugin provides the following goals to run on a Java application:

  1. client:compile – AOT compilation of the application for the target platform
  2. client:link – Links the compiled code with the required libraries to generates the native executable
  3. client:build – Combines client:compile and client:link
  4. client:run – Runs the executable in the target platform

client:build can be executed on our application to create a native executable:

mvn client:build

A native image is created after the above goal has finished successfully. The native image can be executed via mvn client:run and it should show the exact same stage that we had seen earlier:

mvn client:run

This blog post was a quick guide on how to use Gluon Substrate and Gluon Client Maven plugin on a Java application to produce native image. The example shown in the blog post is a part of the client-samples repository in Github and the sample is located at client-samples/Maven/HelloFX. The Maven archetype used in this post is a part of the client maven archetypes.

Please try Gluon Substrate on your Java application, create native images and enjoy the lightning fast startup. If you want to report issues, head over to Gluon Substrate Github repository.

For any feedback, please feel free to contact us.