GraalVM to Level Up JavaFX and Gluon Substrate

Olga Gupalo
graalvm
Published in
7 min readOct 15, 2021

This is a guest blog post written by Johan Vos from the Gluon team.

Recently, more and more users want to create desktop applications that will then run on both mobile and embedded clients. That has been Gluon’s mission — to bring this functionality to JavaFX users. The number of JavaFX SDK downloads both from the Gluon website and Maven Central illustrates the fast growing popularity of JavaFX.

We believe JavaFX is at a pivotal point in the IT industry. JavaFX combines the power of computations that can be done in the backend or locally with strong visualization, all in the same language — Java. You don’t have to use C/C++ for computations and then apply some UI-oriented language for doing the visualization part.

But then there’s the need for speed: faster startup and lower memory requirements. And, as always, the pursuit of increased security. That’s where GraalVM comes in.

GraalVM’s unique features, combined with JavaFX and Gluon’s functionality, make a powerhouse team. GraalVM not only decreases the footprint of the application, speeding up startup time, it also reduces security risks.

This article describes how JavaFX, Gluon Substrate, and GraalVM work together to help users create powerful, flexible desktop apps that can also run on mobile and embedded clients. Then it shows how to quickly create a sample app, and points you towards apps already on the market taking advantage of this winning combination.

JavaFX, Gluon Substrate, and GraalVM Native Image

Besides being a versatile platform for desktop applications, JavaFX with the Gluon Substrate support allows for GraalVM Native Image to transform Java bytecode into an executable, and then add some functionality to the object file to bundle it with everything required. It’s an excellent opportunity because the end users don’t need to worry about the system’s JDK or anything like that. At this point, a JavaFX application is just a native application like any other on the user’s system.

Thanks to the closed-world analysis performed by the native-image utility, only the code that is required by an application is compiled and linked into the final native executable. This decreases the footprint of the application, and also reduces security risks, since vulnerabilities in code that is not used by your application won’t exist in the final image.

GraalVM is a huge benefit when it comes to interoperability with iOS: dynamically compiled code is not permitted by the Apple terms and conditions to execute on iOS devices. To overcome this limitation, all bytecode needs to be compiled into native iOS code in advance. That is something that GraalVM Native Image is doing. Ahead-of-time compilation with GraalVM Native Image opens more opportunities: code that is pre-compiled before it enters a target device does not need to be compiled on the device anymore. This also directly translates to faster startup and lower memory requirements.

And then there’s the LLVM backend in Native Image that allows you to transpile your Java bytecode into LLVM bitcode, allowing you to use any of the LLVM backend compilers to target iOS. After that, of course, it has to be bundled with all the native code that’s required: the native code for Java class libraries, the native code for JavaFX libraries, the platform-dependent hardware exploration, etc.

Along the way, Gluon Substrate helps you with all these tasks: your application code and its dependencies will be discovered by Gluon Substrate. It will pull in a required SDK for Java which contains static libraries, and the SDK for JavaFX containing the static libraries for JavaFX. After that GraalVM Native Image will be applied to create an object file, and bundle everything. As a result, you get an application that runs on a desktop, on a mobile, or embedded client.

Create Your First JavaFX App with Gluon Substrate and GraalVM

There are two approaches to get started with JavaFX: download the SDK locally, or use Maven. If you download the SDK, besides the JavaFX libraries, you also download the native libraries. If you download from Maven, the native libraries are part of the JAR file that you download for your specific platform.

There are also IDE plugins to help developers get started with JavaFX as quickly as possible in NetBeans, IntelliJ IDEA, or Eclipse, and you don’t have to worry about that “lower level” part of JavaFX.

Lastly, and this is probably the easiest way, you can generate a JavaFX project at the Gluon Start website where you can select a Java version, cherrypick Gluon features, preview pom.xml, etc.

Let’s use the wizard at start.gluon.io to create a JavaFX project from scratch:

1. Navigate to start.gluon.io and select the JavaFX version. You may keep all other pre-populated fields as is. Then press Generate Project. The archive, gluon-application.zip, will be saved to your downloads folder (if that is your default location).

2. Navigate to the downloads folder, unzip the archive, change to the project folder, and you’re almost ready to go:

cd Downloads/ && unzip gluon-application.zip && cd demo

3. You can immediately run this demo as a desktop application on the HotSpot JVM using this command: mvn gluonfx:run. But, of course, you should go further and create a self-contained native executable, utilizing Gluon Substrate’s built-in support for GraalVM Native Image.

4. Download GraalVM on your system (based on Java 11 or higher), unzip it, and set the GRAALVM_HOME environment variable that the Gluon Maven build relies on. For example, if you installed GraalVM Java 22.1.0 on macOS, then the command would be:

export GRAALVM_HOME=/Library/Java/JavaVirtualMachines/graalvm-ee-java17-22.1.0/Contents/Home

5. You can now run this demo as a native app with a single command:

mvn gluonfx:build gluonfx:nativerun

Building an image may take some time. It depends on the amount of RAM and the number of cores your machine has. It will compile the code for your OS architecture (in my case, Apple Darwin x86_64).

However, if your JavaFX application is more than a “helloworld” program, you should run it first with the Java agent before building a native executable. The agent tool will trace the execution path and generate the necessary configuration files for the native-image builder:

mvn gluonfx:runagent

Now build and run your JavaFX application as a native self-contained executable: mvn gluonfx:build gluonfx:nativerun.

Notice how fast it starts. The footprint of this simple application itself is 76M. It’s the size of a small microservice, and you can compress it even more with the upx tool (on Linux only):

$ ls -lh target/gluonfx/x86_64-darwin/demo
-rwxr-xr-x 1 <user> staff 76M Aug 4 12:25 target/gluonfx/x86_64-darwin/demo

In our case, the memory consumption is minimal but, of course, it will depend on the images and media that your JavaFX app uses. Typically, in modern applications, the code size is smaller than an image. You can still influence the maximum heap memory your JavaFX app can consume when running as a native image. Let’s say you want to give it only 10M of memory, run:

./target/gluonfx/x86_64-darwin/demo -Xmx10M

The README.md generated by the Gluon Start wizard provides quick instructions which, besides the above steps, tell how to build and run the demo as a native iOS image:

mvn -Pios gluonfx:build gluonfx:package gluonfx:install gluonfx:nativerun

Or as a native Android image:

mvn -Pandroid gluonfx:build gluonfx:package gluonfx:install gluonfx:nativerun

For a more sophisticated example, have a look at the already famous SpaceFX game that runs as a native application. It is suited for playing as a desktop game, on embedded, or mobile devices with 60 frames per second (FPS) responsiveness. And it’s fun.

Other applications built with Gluon Substrate — compiled with GraalVM Native Image — are available at the AppStore or Google Play, including MiniGolf, a 9-hole miniature golf game, and Watchdog for eBay:

Summary

Users want to create desktop applications that will then run on both mobile and embedded clients. Gluon’s mission is to bring JavaFX back to the clients as first-class citizens in order to connect those clients with enterprise software, cloud sources, microservices, and so on. Gluon Substrate is the tool to achieve that.

And then how do you add functionality, reduce footprint, increase security, and significantly speed up startup time? By compiling it as a native executable with GraalVM Native Image. I believe GraalVM is one of the biggest changes in the 25 plus years of Java, and the combination of GraalVM and Java is still going strong; with the 12 million developers worldwide, it is going to set the mark over the next 25 years.

Together, JavaFX, Gluon Substrate, and GraalVM have clear prospects for empowering Java applications for desktops, mobile, or embedded devices. Our community is continuously increasing and, together, we are dedicated to keeping up with their needs.

--

--