von José Pereda Llamas und Wolfgang Weigend
Beginnen wir mit einem realen Anwendungsfall: In einem GitHub-Beitrag zu OpenJFX von John Neffenger findet sich ein interessanter Anwendungsfall. In den Release Notes zur Unterstützung für E-Paper-Displays auf i.MX-6-Geräten beschriebt er die Installation von Ubuntu auf den E-Paper-Geräten Amazon Kindle und Rakuten Kobo. Eine Hürde bestand darin, die Entwicklung von Anwendungssoftware für E-Paper-Devices zu vereinfachen, die auch auf Desktopplattformen ausgeführt werden kann, ohne dass der Quellcode neu kompiliert oder geändert werden muss.
John suchte nach verschiedenen Lösungen, um das zu erreichen: Die Verwendung von Qt für Embedded Linux war keine Option, weil die Pläne zur Unterstützung von Qt-Embedded-Plattformen noch in einer frühen Phase sind. Flutter und Dart kamen ebenfalls nicht in Frage. Die Flutter-Community kommuniziert, dass Flutter auf dem Desktop oder bei Embedded-Geräten keine Priorität hat.
Schließlich gelang es John, mit Unterstützung der JavaFX-Community, Ubuntu, Java und JavaFX auf einem E-Reader zu installieren. Im Januar 2019 stellte er folgende JavaFX-Anfrage per GitHub OpenJFX Request: Geräteunterstützung mit elektrophoretischen Displays (E-Paper-Displays) mittels einer neuen Monocle-Plattform namens EPD. Nach einigen Projektänderungen wurde sein GitHub Pull Request angenommen. Somit ist JavaFX 13 die erste OpenJFX-Version mit Unterstützung für E-Paper. Daraus ergibt sich, dass jede JavaFX-Anwendung auf E-Paper-Displays funktioniert.
Eine weitere Schwierigkeit bestand darin, dass diese Displays inhärente Grenzen für Graustufen und Bildraten haben. Einige Anwendungen, die für LCD-Bildschirme geschrieben wurden, sind so möglicherweise nicht für sie geeignet.
John begann mit der Unterstützung solcher JavaFX-Klassen und Steuerelemente, die die Schwarz-Weiß-Animationsfunktionen des E-Papers mit Bildraten von bis zu acht Bildern pro Sekunde ermöglichen. In einem Folge-Request schlug John vor, die Unterstützung für E-Paper-Displays mit den Anwendungsprozessoren der i.MX-6-Serie hinzuzufügen. Diese Anforderung wurde in JavaFX 15 implementiert.
Der Anwendungsfall zeigt nicht nur, dass der Java-Communityprozess funktioniert, sondern auch, dass JavaFX ein Framework ist, mit dem eine Benutzeroberfläche für Anwendungen erstellt werden kann, die auf einem beliebigen Gerätetyp ausgeführt werden, sei es auf dem Desktop, mobilen Geräten oder Embedded-Systemen.
JavaFX auf beliebigen Gerätetypen
Die verschiedenen Implementierungen von JavaFX enthalten Komponenten, die für die gängigen Plattformen gemeinsam genutzt werden. Andere Komponenten sind plattformspezifisch. Im Embedded-Markt sind viele Kombinationen möglich, die unterschiedliche CPU-Architekturen, Betriebssysteme, GPUs und grafische Treiber umfassen. Das Erstellen von JavaFX Builds für jede mögliche Kombination kann schwierig sein. Zur Vereinfachung hat die Firma Gluon, verantwortlich für die Wartung und Freigabe von JavaFX, ein Werkzeug entwickelt, mit dem die Kunden benutzerdefinierte JavaFX 16 Early Access Builds erzeugen (Abb. 1). Das gilt für Linux-basierte Geräte mit einem ARM32- oder ARM64-Prozessor, wie sie zum Beispiel in einem Raspberry Pi verwendet werden. Mit den JavaFX 16 EA Builds können die Entwickler auf allen Embedded-Geräten experimentieren.
John hat bei der Entwicklung von E-Reader-Anwendungen seine Klassendateien auf dem Desktop kompiliert und den Java-Bytecode auf der JVM seines Geräts ausgeführt. Das reicht jedoch für die bestehenden Anforderungen nicht aus, da die erstellten Apps sofort geladen werden müssen, anstatt auf den Start einer JVM inklusive des Ladens von Klassen zu warten. Zielführend ist die Erstellung von Anwendungen, die mit der gleichen Geschwindigkeit ausgeführt werden, wie sie native Apps erreichen.
GraalVM zur plattformübergreifenden Entwicklung
Beim Erstellen mobiler Anwendungen haben Java-Entwickler oftmals Vorbehalte, auf die nachfolgenden Ansätze zurückzugreifen:
- Erstellen einer eingebundenen Browser-App mit HTML, JavaScript und CSS
- Verwenden von Plattformen wie React Native oder Flutter
- Erstellen nativer iOS- und Android-Apps
Bei diesen Lösungen müssen Java-Entwickler ihre vertraute Java-Umgebung verlassen. Gluon hat ein vollständiges Toolset erstellt, mit dem Java-Entwickler mobile Apps vom Backend bis zum Frontend programmieren können. Die Gluon-Mobile-Werkzeuge können als Plug-in für die gängigsten IDEs verwendet werden. Gluon Substrate nutzt den GraalVM-Native-Image-Compiler und ist das Bindeglied zum Cross-Plattform-Binary.
Technologieunternehmen wie Oracle, Amazon, Microsoft und Red Hat arbeiten an einer Lösung für die plattformübergreifende Entwicklung nativer Anwendungen. Durch einmaliges Codieren und anschließendes Kompilieren auf MS Windows, iOS, Android und Embedded-Systemen können Entwickler eine stabile und robuste Programmiersprache standardisieren, anstatt kurzlebige Frameworks wie React Native (Facebook) oder Flutter (Google) auf der Clientseite zu verwenden.
Der Java-Bytecode-Interpreter verlangsamte zunächst das Laufzeitverhalten. Mit der Einführung von Just-in-Time-(JIT-)Compilern (wie den Hotspot-Compilern C1 und C2), um Code zu kompilieren, der häufig in nativem Code verwendet wird, änderte sich das. C1 ist ein schneller Compiler, der zu nativem und schnellem Code kompiliert. C2 ist ein langsamer Compiler, aber der generierte native Code ist viel schneller. Außerdem kompiliert C2 Code zur Laufzeit, wodurch die Ausgabe verlangsamt wird. C2 wurde in C++ geschrieben und der komplexe Code ist schwer zu pflegen. Das ist einer der vielen Gründe, warum die Oracle-Labs-Entwickler einen neuen JIT-Compiler von Grund auf neu geschrieben haben. Die GraalVM ist vollständig in Java geschrieben, basiert auf zahlreichen akademischen Forschungen und ist einfacher zu warten als der Hotspot-C2-Compiler. Darüber hinaus enthält die GraalVM auch einen Ahead-of-Time-(AOT-)Compiler. Mit GraalVM Native Image können die Entwickler Java mit anderem Code, etwa in C++ oder Python geschriebenem, zu einem nativen Image als ausführbare Binärdatei kompilieren. Die komplexe Aufgabe, ein GraalVM Native Image zu erstellen, nimmt der Entwickler durch Parametereinstellungen und Abhängigkeitsbetrachtung vor.
Bei der Verwendung vom GraalVM Native Image übernimmt Gluon Substrate den größten Komplexitätsanteil. Die Java-App wird erstellt und auf dem Desktop getestet, dann wird der Java-Bytecode kompiliert und mit einem nativen Image für die ausgewählte Plattform verknüpft, indem ein Maven-Profil definiert wird. Die resultierende Binärdatei kann im App Store oder bei Google Play bereitgestellt werden. Die Native-Image-Funktion der GraalVM eröffnet dabei auch neue Einsatzmöglichkeiten für JavaFX.
Auswirkungen auf die mobile Anwendungsentwicklung
Eine für den Desktop erstellte Benutzeroberfläche ist nicht als Benutzeroberfläche für ein mobiles Gerät geeignet und umgekehrt. Auf einem Smartphone ist beispielsweise keine Tastatur oder Maus vorhanden, stattdessen existieren ein Touchscreen und eine virtuelle Tastatur, die einen Teil der Benutzeroberfläche abdeckt.
JavaFX wird aktiv entwickelt, um die verschiedenen Layoutvarianten zu unterstützen, die den unterschiedlichen Benutzerinteraktionen auf dem verwendeten Gerät entsprechen. Mit dem JavaFX Scene Builder, einem WYSIWYG-Werkzeug, können die Benutzeroberflächen durch Ziehen und Ablegen von Steuerelementen aus einer Palette erstellt werden (Abb. 2). Der Scene Builder kann als eigenständiger Designer oder als Plug-in für die bevorzugte IDE verwendet werden. Diese Informationen werden als FXML-Datei in einem speziellen XML-Format gespeichert.
Zu den verfügbaren Steuerelementen in OpenJFX kommen noch weitere JavaFX Controls aus der Community. Das ControlsFX-Projekt bietet eine Reihe hochwertiger UI-Steuerelemente, die die initiale JavaFX-Distribution ergänzen. ControlsFX umfasst eine Bewertungssteuerung mit Sternen, Kippschalter, Benachrichtigungsfenster, Master-Detail-Steuerelementen, Tabellenkalkulationen und eine Task Progress View (Abb. 3) sowie viele weitere JavaFX-Steuerelemente (etwa die in Abb. 4 gezeigte MaskerPane).
Das UI-Framework Glisten (Abb. 5) für JavaFX basiert auf dem Material Design von Google und bietet eine professionelle und intuitive Oberflächenhandhabung, die die App-Benutzer erwarten und einfordern. Darüber hinaus kann Glisten Afterburner verwendet werden, um beim Erstellen der UI-Ansichten Zeit zu sparen, wenn Konventionen anstelle von Konfigurationspatterns und Dependency Injection bei der View-Erstellung verwendet werden sollen.
Beim Erstellen mobiler Apps werden Funktionen verwendet, die spezifisch für mobile Geräte sind:
- vorhandene Akkulaufzeit überprüfen
- Bilder mit der Gerätekamera aufnehmen
- aktuellen Standort ermitteln und diesen Standort auf einer Karte anzeigen
- weitere individuelle Funktionen
Der Code, um diese Funktionalität unter iOS zu erreichen, unterscheidet sich von dem Code, der für Android benötigt wird. Das erschwert die Arbeit, wenn der Code nur einmal entwickelt und überall ausgeführt werden soll. Gluon bietet eine Abstraktionsschicht, sodass man sich nicht um den zugrunde liegenden nativen Code kümmern muss. Die Anbindung von Datenquellen wird über Gluon Connect hergestellt und wenn geografische Karten verwendet werden, benötigt man die Maps-Komponente von Gluon. Die Entwickler müssen sich übrigens nicht um die Konfiguration ihrer Anwendungsabhängigkeiten kümmern, weil das von Gluon Start angeboten wird (Abb. 6).
Mit Gluon Start kann man die gewünschte JavaFX-Version auswählen und die benötigten Module mit den Gluon-Funktionen anklicken. Ein Klick auf PROJEKTVORSCHAU zeigt die Projekt-POM-Datei (Abb. 7). Mit dem Klick auf den Button PROJEKT GENERIEREN wird eine ZIP-Datei mit dem Projekt erstellt, die man in die bevorzugte IDE importieren kann.
Neben den Gluon-Komponenten können die Entwickler auch andere Bibliotheken in ihren Anwendungen verwenden. Der Vorteil der Java-Plattform besteht im Zugriff auf eine umfangreiche Sammlung robuster Java-Bibliotheken und auf Projekte wie Micronaut, Quarkus, Helidon, DL4J (Eclipse Deeplearning4j) oder Tribuo (eine Machine-Learning-Bibliothek für Java).
Künstliche Intelligenz als Anwendungsfall für den Java-Client
Es gibt nur wenige mobile Anwendungen, die auf einem Gerät ausgeführt werden, ohne Verbindung zu einem Backend herzustellen. Beim Anwendungsdesign werden oft Kompromisse gemacht, die zu Einschränkungen führen. Dabei stellen sich unterschiedliche Fragen:
- Verwendet man die Geräte-CPU oder verlagert man den Verarbeitungsaufwand auf das Backend? Hier könnte man argumentieren, dass im Frontend weniger Funktionen benötigt werden, wenn die gesamte Arbeit im Backend abgearbeitet werden kann, aber diese Entscheidung ist nicht trivial.
- Wie viel Bandbreite steht zur Verfügung, um die Daten zwischen dem Backend und dem Frontend zu übertragen? Diese Frage bestimmt den Umgang mit IoT-Geräten.
- Möchte man tatsächlich, dass ein Sensor alle aufgenommenen Daten an das Backend sendet, oder möchte man eher, dass das Gerät intelligent genug ist, um selbst eine Auswahl der relevanten Daten zu treffen? Im Zusammenhang mit dem Datenschutz sollten Sie prüfen, ob es gesetzlich zulässig ist, die auf dem Gerät gesammelten Daten an ein Backend zu senden. Das ist möglicherweise nicht immer der Fall, zum Beispiel aus Geheimhaltungsgründen oder zur Wahrung der Privatsphäre.
Am Beispiel der Java-AI-Bibliotheken mit Gluon Mobile ist beschrieben, wie eine Anwendung mit der Prediction-Bibliothek von Oracle namens Tribuo erstellt werden kann (Abb. 8). Die App liest einen Datensatz, trainiert ein Modell und wertet es aus. Es gibt drei mögliche Ergebnisse, und JavaFX wird zur Visualisierung verwendet, um die Anzahl der korrekten Vorhersagen (TP) sowie die falschen Vorhersagen (FP) für jedes Ergebnis darzustellen. Dieser Anwendungsfall in Kombination mit einer Java-AI-Bibliothek mit JavaFX auf dem Client ist unabhängig davon, ob es sich um einen Desktop, einen Laptop, ein Mobile- oder ein Embedded-Gerät handelt.
JavaFX Long Term Support (LTS)
Um die SDK-Versionen von Java regelmäßig zu bereinigen, zieht Oracle bei verschiedenen Gelegenheiten Non-JDK-Core-Module heraus. Das kann entweder geschehen, um sie in den Ruhestand zu versetzen oder weil es an der Zeit ist, diese technologischen Fragmente als unabhängige Module selbstständig gedeihen zu lassen. Das erste Szenario trifft auf JavaFX nicht zu. Das zweite Szenario ist eine Gelegenheit, die mehr Flexibilität ermöglicht, um die Roadmap schneller an spezifische Anforderungen anzupassen. Zum Beispiel, wenn Unterstützung für neue Grafiktreiber benötigt wird. Ein Risiko besteht dennoch, dass das zum Stillstand durch Inkubation führen kann – etwas, das passiert, wenn der ursprüngliche Entwickler darauf setzt, dass Dritte neue Versionen eines Produkts erschaffen. Nachdem Oracle JavaFX 11 mit Java SE 11 aus dem Java Development Kit herausgetrennt hatte, übernahm Gluon die Verantwortung, die UI-Technologie zu unterstützen und zu warten sowie neue Releases zu erstellen. Alle JavaFX Code Contributions unterliegen einem gemeinsamen Codereviewprozess durch das Oracle JavaFX Engineering und das Gluon Engineering. Die Gluon JavaFX LTS Subscription speist die Engineering-Aufwände und Unternehmen können sich auf das Gluon-Team verlassen, wenn es um Backports von kritischen Problemen und Sicherheitspatches geht. Damit wird Kontinuität für individuelle Kundenbetriebsumgebungen angestrebt, um die Lebensdauer der Java-Entwicklungsinvestitionen langfristig abzusichern. Gleichermaßen können Unternehmen auch Einfluss auf die Roadmap von JavaFX nehmen, wenn sie bestimmte Verbesserungen benötigen.
Fazit und Ausblick
Seit der ersten Veröffentlichung von JavaFX im Jahr 2008 hat die Java-UI-Technologie Höhen und Tiefen erlebt, kommt aber gestärkt aus dieser Zeit heraus. Der Mobile-Technologie-Stack von Gluon beweist, dass JavaFX lebendig und erfolgreich ist. Nach langer Reifezeit ergeben sich neue Chancen für JavaFX, aus dem Nischendasein in den Desktopanwendungen herauszukommen und auf Mobilgeräten und Embedded-Systemen Fuß zu fassen. Die Kombination von Java und der JavaFX-UI-Technologie mit der AOT-Compiler-Fähigkeit der GraalVM zur Erstellung von eigenständig ausführbaren nativen Images mit geringerem Speicherverbrauch und verbesserter Start-up-Zeit führt zur Ausbreitung von Java im Bereich der Systementwicklung. Vom Backend bis zum Frontend gelingt durch Unterstützung von Gluon Mobile für die Plattformen iOS und Android (inklusive Unterstützung für zentrales Cross-Kompilieren von Java-Anwendungen mit JavaFX) echtes Cross-Plattform-Deployment für JavaFX-Anwendungen. Bemerkenswert ist der positive Trend der JavaFX-UI-Technologie, der sich in zunehmenden Downloadzahlen bei Maven Central und den konkreten Projektdiskussionen beim JavaFX-Anwendertreffen 2020 manifestiert. Das JFX Adopter Meeting am 14. Oktober 2020 wurde vom FORUM Team der Firma Carl Zeiss Meditec koordiniert.
Links und Literatur
[1] https://gluonhq.com/products/javafx/
[2] https://www.oracle.com/java/technologies/javase/javafx-overview.html
Spring Ecosystem auf der JAX & W-JAX:
● Workshop: Coole neue Java-Features – besserer Code mit Java 9 bis 15
● Neues in Java