JavaFX in the new era of GraalVM


This article was originally posted in Java magazin (in German).

In September 2020, JavaFX 15 was released, which makes an ideal occasion for us to philosophize on why JavaFX is more relevant than ever. In this article, we’ll go beyond JavaFX on the desktop, and even beyond JavaFX on mobile. We’ll talk about cross-compiling Java applications using JavaFX for the user interface, and about using Java from the back end to the front end.

The goal of every new release of JavaFX is to ensure that existing applications using JavaFX continue working at least as fine as with the previous release, while supporting more software and hardware drivers. That may not be as hip as the gimmicks other platforms use to please the masses, but stability and compatibility are key for developers and companies who are depending on Java and JavaFX in their mission critical applications.

We’ll start by taking a closer look at a contribution by John Neffenger, a gem that was hidden behind the line “support for e-paper displays on i.MX6 devices” in the release notes.

ePaper, an Interesting Use Case for JavaFX

After many hours of experimenting, John succeeded in installing Ubuntu on ePaper devices such as the Amazon Kindle and Rakuten Kobo eReaders. The next hurdle was making it easy to develop application software for e-paper that can also run on desktop platforms without having to recompile or modify the source code in any way.

He looked at different possible solutions to make this happen:

  • Using Qt for Embedded Linux wasn’t an option; he was told that plans to support embedded platforms for Qt were in their earliest stages.
  • Flutter and Dart were out of the question too; the Flutter community informed him that Flutter on the desktop or embedded wasn’t considered a priority.
  • He succeeded in installing Ubuntu, Java, and JavaFX on an eReader, and he received a positive response when he reached out to the people responsible for JavaFX.

On January 7, 2019, John submitted the following request:

“This is a request for JavaFX to support devices with electrophoretic displays, commonly known as electronic paper displays, with a new Monocle platform called EPD.”

He pushed some changes to the project on Github and his pull request was accepted. As a result, JavaFX 13 was the first OpenJFX version with support for ePaper.

It wasn’t John’s intention that just any JavaFX application would work well on e-paper displays. These displays have inherent limits in grayscale levels and frame rates, so some applications written for LCD screens may never be appropriate for them. He started with adding support for those JavaFX classes and controls that would enable the black-and-white animation capabilities of e-paper, with frame rates up to eight frames per second. In a follow-up request, John suggested adding support for ePaper displays with the i.MX 6 Series of application processors. The implementation of this request made it into the JavaFX 15 release.

This use case proves not only that the community process works, but also that JavaFX is a framework designed to create a UI for applications running on any type of device, whether for the desktop, mobile devices, or embedded systems.

JavaFX on Any Device

Obviously, the different implementations of JavaFX contain components that are shared across some or all platforms, and some components are specific to specific platforms. The embedded market is very diverse. There are many combinations possible that involve different CPU architectures, operating systems, GPU’s, and graphical drivers. Creating the JavaFX build for each possible combination can be a pain.

To take away that pain, Gluon, the company responsible for maintaining and releasing JavaFX, has built a tool that allows its customers to create custom early-access JavaFX 16 builds for linux-based devices with an ARM32 or an ARM64 processor, e.g. the Raspberry Pi. These builds will allow developers to experiment with JavaFX on all kinds of embedded devices.

Figure 1: Creating Custom Builds for OpenJFX

In the example of writing applications for eReaders, John compiled and jarred his class files on the desktop, and he ran the java bytecode on his device’s JVM. That may not be sufficient for your needs. You may want to create apps that load instantly, instead of having to wait for a JVM to start, classes to be loaded, and so on. You may want to create applications with a speed that can only be matched with native apps.

In that case, you should read on, and learn more about AOT-compiling with GraalVM.

GraalVM, the Holy Graal of Cross-platform Development

When creating mobile applications, Java developers sometimes fear they’ll be forced to resort to:

  • Making an in-browser app that involves HTML, JavaScript, and CSS, or
  • Using platforms such as React Native or Flutter, or
  • Creating native iOS and Android apps.

While these solutions work, they require Java developers to leave their familiar Java environment.
Fortunately, such discomfort can be avoided. Gluon has built a full stack of tools that allow developers to build mobile apps using Java from the back end to the front end. The umbrella name for these tools is Gluon Mobile, and you can use most of them as a plug-in for the most common IDEs.

Gluon Substrate for instance, uses the GraalVM native image compiler under the hood.

What is GraalVM?

Technology companies such as Oracle, Amazon, Microsoft and Redhat have incessantly been working on a solution for cross-platform development of native applications. Writing code once, and then compiling to Windows, iOS, Android, Embedded, allows developers to standardize on a stable and robust programming language instead of having to use usually short-lived frameworks such as ReactNative (Facebook) or Flutter (Google) on the client side.
Originally Java was slow because the Java bytecode was interpreted. This changed with the introduction of Just-In-Time (JIT) compilers, such as the Hotspot C1 and C2 compilers, to compile code that is frequently used into native code. C1 is a fast compiler that compiles to native code that is fast. C2 is a slow compiler, but the generated native code is much faster. Also, C2 compiles code at runtime, which slows the output down.
C2 was written in C ++ and its complex code is very difficult to maintain. This is one of the many reasons why Oracle Labs decided to write a new JIT from scratch. GraalVM, as it’s called, is written in Java, it’s based on plenty of academic research, and it’s much easier to maintain than C2. Moreover, GraalVM also includes an Ahead-Of-Time (AOT) compiler, GraalVM Native Image, that allows developers to compile Java —and other code, such as C++, Python…— into a native image.
The only threshold for developers to adopt GraalVM Native Image is its complexity. Many parameters must be set; there are many dependencies to be kept in mind.

Gluon Substrate takes away most of the complexity of using GraalVM Native Image. You can create an app in Java, test it on your desktop, and then compile and link the Java bytecode to a native image for a specific platform by defining a profile in Maven. The resulting binary can be deployed to the AppStore or Google Play. For a short intro on how this works, see this video about creating an app for iOS using the Gluon plug-in in Netbeans.

It’s needless to say that GraalVM Native Image opens an abundance of opportunities for JavaFX. Let’s take a look at the impact this evolution could have on the development of mobile applications.

Mobile Development Made Easy

A user interface created for the desktop usually isn’t ideal as a UI for a mobile device, and vice versa. You must consider that there’s no keyboard or mouse present on a smartphone. Instead you have a touch screen and a virtual keyboard that covers part of the UI.

JavaFX is actively developed to support different types of layouts, matching the many ways in which people interact with the device they are using. The best way to explore the possibilities of JavaFX, is by using a Scene Builder, a WYSIWYG tool that is supported and maintained by Gluon.

What is Scene Builder?

Scene Builder allows you to create a UI by dragging and dropping controls. It can be used as a standalone designer, or as a plug-in for your favorite IDE. This avoids having to hack your own FXML files.

Figure 2: Creating a UI with Scene Builder

You’ll soon discover that you’re not limited to using the controls that are available in OpenJFX. The ControlsFX project for instance, provides a series of high-quality UI controls that complement the core JavaFX distribution. For instance, a rating control with stars, a toggle switch, advanced notification panes, master detail, spreadsheet, and task progress views…

Figure 3: Example of a MasterPane

Figure 4: Example of a Task Progress View

Glisten is another UI framework built on top of JavaFX. It’s based on Google’s Material Design that gives you the slick and intuitive user experience the users of your app expect and demand. Additionally, you can use Glisten Afterburner to save time when creating your views by using the convention over configuration pattern and dependency injection.

Figure 5: Examples of a UI created using Glisten

When creating mobile apps, you probably want to use functionality that is specific to mobile devices, such as:

  • checking how much battery life is left,
  • capturing images with the device’s camera,
  • obtaining the current location and showing that location on a map,
  • and much more.

The code to achieve this on iOS is different from the code you need on Android, which complicates things when you want to write your code only once and run it everywhere. Gluon provides an abstraction layer so that you don’t need to worry about the underlying native code.

If you want to connect to data sources, you’ll need Gluon Connect; if maps are involved, you’ll need the Gluon Maps component. Developers don’t have to worry about configuring their application dependencies, this can be done using “Gluon Start”.

Figure 6: Create your Project with Gluon Start

Select the JavaFX version, the modules you need, and the Gluon features you want to use. Hitting “Preview Project” will allow you to take a look at the POM file of your project; hitting “Generate Project” will create a zip-file with a project that you can import into your favorite IDE.

Figure 7: Preview of a POM file created with Gluon Start

Developers aren’t limited to using Gluon components in their applications. The advantage of using the Java platform from back end to front end, is access to a vast collection of robust Java libraries and projects, such as Micronaut, Quarkus, DL4J, Tribuo, and so on.

Artificial Intelligence, an Interesting Use Case for Java on the Client

There are very few mobile applications that run on a device without connecting to a back end. When designing an application, you always make trade-offs. Do you use CPU on the device, or do you offload processing efforts to the back end? You could argue that there isn’t that much functionality needed on the front end if all the work can be done on the back end, but making that call usually isn’t that trivial. How much bandwidth can you afford using when transferring data between the back end and the front end? This question is important when dealing with IoT devices. Do you really want a sensor to send all the data it registers to the back end, or do you want the device to be intelligent enough to make a selection of data that is relevant? In the context of privacy, you should check if it’s legally allowed to send the data that is collected on the device to a back end. That may not always be the case —e.g. for reasons of privacy.

In the article Java AI libraries with Gluon Mobile, you can read how you can create a simple sample application involving Oracle’s prediction library Tribuo. This app reads a data set, trains a model, and evaluates that model. There are three possible outcomes, and JavaFX is used to visualize the number of correct predictions (TP) as well as the wrong predictions (FP) for each outcome.

Figure 8: Tribuo Sample App

This is an interesting use case of combining an AI Java library with JavaFX on the client, regardless whether it is a desktop, a laptop, a mobile device, or an embedded device.

JavaFX Long-Term Support (LTS)

We’ve all heard rumors about the death of JavaFX and we all know that they were just that: rumors. With the Gluon Mobile technology stack, Gluon proves that JavaFX is alive and kicking.

To keep its Java SDK releases clean, Oracle chooses to pull out non-core modules on different occasions. This can happen either to retire them, or because it’s time to let them thrive on their own as independent modules. The former scenario happens with technology that already has one foot in the grave; that wasn’t —and clearly isn’t— the case for JavaFX. The latter scenario is an opportunity that allows more flexibility to quickly adapt the roadmap to meet specific requirements, e.g. when support for new graphical drivers is needed. It also comes with a risk, as it can lead to “death by incubation” —something that happens when the original creator counts on third parties to hatch new versions of a product.

After Oracle removed JavaFX from the Java Development Kit starting with Java 11, Gluon took upon itself the responsibility to support and maintain the technology, and to create new releases. By subscribing to Gluon’s LTS for a small yearly fee, companies can count on the Gluon team for backports of all the critical issues and security patches. They can ensure themselves of continuity for their operational environment and of a longer lifespan for their java development investment. By becoming a Gluon customer, companies can also have an impact on the JavaFX roadmap, for instance if they require specific enhancements.

Visit gluonhq.com for more information, and don’t forget to try start.gluon.io to build your first Gluon Mobile project.