Posts

Turning JavaFX apps into native images

Aug 24, 2022
Peter Zhelezniakov
5.8

In our recent guide to JavaFX, we summarized the key features of this platform and compared it to the most prominent competitors. If you are still wondering whether JavaFX is worth learning, refer to the guide. For those of you who have already mastered the software, we suggest going a step further and integrate it with native image technology. So let’s get our hands dirty and turn a JavaFX application into a native executable using Liberica Native Image Kit!

  1. What is Liberica Native Image Kit?
  2. Turn a JavaFX app into a native image!
    1. Enable native compilation
    2. Compile the application
    3. Speed and memory comparison
    4. Limitations
  3. Conclusion

What is Liberica Native Image Kit?

Liberica Native Image Kit (NIK) is a utility based on the GraalVM Community Edition. It helps to convert JVM-based applications into native executables. Liberica NIK enhances the experience of writing desktop applications as the native image takes up less disc space and starts up almost instantly.

The benefits of using Liberica NIK in your enterprise development:

  • Supports a wide variety of platforms, features, and languages. We support Windows, Linux, and MacOS, including ARM-based Macs. Starting with version 21.3, Liberica NIK works with AWT/Swing and OpenJFX
  • Always on the latest versions of GraalVM CE and Liberica JDK with eliminated CVEs and bug fixes
  • Receives support from the engineers who develop the product

Turn a JavaFX app into a native image!

Enable native compilation

First, you need to download and install Liberica NIK. Go to the Liberica NIK Download Center and choose NIK version 22 for Java 11 or 17. You need the Full version as it includes LibericaFX, an instance of OpenJFX.

Download the package and follow the instructions to install the utility on your platform. macOS users should get the .dmg package to avoid any issues with running Liberica NIK.

You are now ready to compile Java applications natively. You have several options:

  • Manual invocation. From your NIK installation, run native-image <args> -jar <your application jar>
  • Configure Maven build as described here
  • Configure Gradle build as described here

In all three cases, your application is likely to use resources such as icons or images. These resources must be made known to native-image so that it includes them in the resulting executable. There are two options to include and exclude resource identifiers, and you can use wildcards there:
-H:IncludeResources='com.fxapp.resources.images.*'
-H:ExcludeResources='com.fxapp.resources.unused.*'

Alternatively, resources can be configured using JSON files. Many applications make use of dynamic language features such as reflective or JNI access. In this case, the feature being used, such as the name of the method called, is not known at image build time, so NIK cannot figure out exactly which method is called. These dynamic feature usages must be configured beforehand using JSON files as described here.

You can create JSON files using the native image agent. Run your application with the agent enabled, probably several times to exercise different code paths. The agent captures dynamic feature accesses and creates configuration files automatically. These files can be passed to native-image without further editing.

Compile the application

Let us now compile a JavaFX app natively. We will use the BrickBreaker game as an example. You can utilize your own app or select a JavaFX demo on GitHub. BrickBreaker requires no dynamic feature configuration. At the same time, it uses lots of images that need to be included in the resulting executable. In this example, image names are passed using -H:IncludeResources with a regular expression:

$ native-image \ -H:IncludeResources='ensemble.samples.shared-resources.brickImages.*' \
 -jar BrickBreaker.jar

After the compilation has finished, run

$ ./BrickBreaker

Natively compiled BrickBreaker demo

Speed and memory comparison

The figures below were obtained on an Intel Core i7 laptop running Ubuntu Linux.

 Liberica JRE 17.0.4.1Native Image made with Liberica NIK 22.2.0-JDK17
Startup time710ms366ms
Maximum RSS176M133M
Executable size276M (JRE+jar)36M

Limitations

Modules javafx.media and javafx.web are currently not supported for native compilation. The javafx.media module is responsible for adding the playback of media and audio content. The javafx.web module defines the WebView functionality.

Conclusion

In this step-by-step tutorial, we learned how to generate JavaFX native images. Liberica NIK can also be used to create tiny containers saving precious cloud resources. Give it a try!

Download Liberica NIK

Subcribe to our newsletter

figure

Read the industry news, receive solutions to your problems, and find the ways to save money.

Further reading