This blog post is about my visit at the JAX 2013 in Mainz, one of the biggest Java conferences of europe. As an
exception this time the post is written in german and not english.
In der letzten Woche hatte ich durch meinen Arbeitgeber die Möglichkeit, die JAX 2013, eine der
größten Java-Konverenzen Europas in Mainz zu besuchen. In diesem Blogpost möchte ich über Vorträge berichten, die ich
besucht habe.
JavaFX
Enterprice Anwendungen mit JavaFX (8)
Adam Bien berichtete in seinem Vortrag "Enterprice Anwendungen mit JavaFX (8)" recht unterhaltsam von seinen
Erfahrungen mit Enterprice Anwendungen und den Dingen, die bei dieser Klasse von Anwendungen seiner Ansicht nach
relevant sind. Er kam zu dem Schluss, dass hier JavaFX in vielen Fällen eine lohnenswerte Alternative zu den klassischen
Webtechnologien sein kann.
Im Verlauf des Vortrags stellte er anschließend seine Vorstellung davon vor, wie Entwickler Oberflächen mit JavaFX
entwickeln sollten. Trotz anfänglicher Skepsis sieht er vor allem FXML, die XML-Basierte Beschreibungssprache für JavaFX
ab Version 2, als ein sehr gutes Werkzeug an. Mit FXML lässt sich eine Oberfläche deklarativ beschreiben und dynamisch
von JavaFX aus laden. In der FXML-Datei kann der Name einer Controller-Klasse angegeben werden, der dann von JavaFX
automatisch instanziiert wird und der per Dependency Injection die benötigten Referenzen auf UI-Elemente erhält. Adam
Bien sieht hier das Prinzip der Inversion of Control sehr gut umgesetzt.
Da für FXML-Dateien auch ein sehr reichhaltiger und ausgereifter WYSIWYG-Editor namens
SceneBuilder existiert, sieht er
diese Vorgehensweise bei der Entwicklung von Desktop-Oberflächen als vorteilhaft an.
Die einzige Lücke, die in diesem Mechanismus noch besteht, ist die Verwendung von echter Dependency Injection für die
Anbindung der Backend-Logik. Der DI-Mechanismus von JavaFX injected nämlich nur UI-Elemente aus der FXML-Datei in den
Controller, andere Abhängigkeiten wie Services werden nicht automatisch eingefügt. Da die Instanziierung des Controllers
ebenfalls von JavaFX übernommen wird, kann der Entwickler auch nicht einfach per händischer Dependency-Injection per
Konstruktor die Abhängigkeiten hineinreichen.
Glücklicherweise ist der DI-Mechanismus von JavaFX relativ leicht erweiterbar und so stellte Adam in seinem Vortrag
auch das von ihm entwickelte Mini-Framework Afterburner.fx vor, welches einfache
DI auf simple Art und Weise umsetzt und dabei, wie andere DI-Frameworks auch, die 'javax.inject'-Annotationen
verwendet.
Wer schon immer mal sehen wollte, wie einfach ein DI-Framework sein kann, der sollte sich unbedingt den
Quellcode von Afterburner.fx auf Github anschauen. Das ganze Framework
besteht nämlich nur aus 2 relativ kleinen Klassen.
JavaFX vs. Html5
Im Vortrag "JavaFX vs. Html5" zeigt Björn Müller einige Anwendungsfälle auf, bei denen HTML5 (in Kombination mit
JavaScript) seiner Ansicht nach nicht die passende UI-Technologie ist, sondern klassische Desktop-Oberflächen besser
geeignet sind. Er bezieht sich vor allem auf große, umfangreiche Business-Applikationen mit umfangreichen Eingabemasken
und mehreren Hundert Screens. Als Beispiele nennt er Anwendungen aus dem Bereich der Logistik und Lagerverwaltung.
Als Gründe nennt er nicht nur die nach wie vor bessere Performance von Desktop-UI's, sondern vor allem die
Entwicklungseffizienz, d.h. wie schnell die Entwickler die entsprechende Funktionalität liefern können.
Als eine mögliche Lösung für die Entwicklung großer Business-Applikationen stellte Björn anschließend das von ihm
entwickelte Framework CaptainCasa vor.
CaptainCasa stellt eine Verbindung des UI-Frameworks JavaFX mit dem Serverseitigen Komponenten-Modell von JavaServer
Faces her. Denn obwohl JSF in den meisten Fällen zur Entwicklung von HTML-Oberflächen genutzt wird, ist es prinzipiell
unabhängig von der tatsächlichen benutzten View-Technologie.
Die Serverseite kann damit klassisch mit JavaEE entwickelt werden, die UI wird mittels JSF und einer speziellen
Tag-Library umgesetzt. Auf Client-Seite kommt statt dem Webbrowser jedoch ein JavaFX-Renderer zum Einsatz. Die UI ist
damit nicht fest im Client implementiert sondern wird dynamisch auf Serverseite generiert und mittels eines
XML-Datenaustauschformats zum Client gesendet, welcher aus diesen Informationen die Oberfläche aufbaut. Eingaben des
Nutzers werden auf ähnliche Weise wieder zum Server gesendet und durchlaufen dort den bekannten JSF-Livecycle.
Für Entwickler, die bereits mit JSF zu tun hatten, ist der Lernaufwand deshalb relativ gering. Sie müssen sich nicht mit
den Details von JavaFX ausseinander setzen, sondern können ihre gewohnten Serverseitigen Technologien aus dem
JavaEE-Umfeld einsetzen. Neu ist lediglich die Tag-Library von CaptainCasa, die jedoch vom Prinzip her nicht wesentlich
anders funktioniert, als bekannte JSF-Libraries.
CustomComponents in JavaFX
Gerrit Grunwald stellte in seinem Vortrag das wesentlich von ihm vorangetriebene Projekt
JFXtras vor, welches eine Sammelstelle für JavaFX-Customcontrols darstellt. Er zeigte, welche
Möglichkeiten JavaFX bietet um selbst Controls herzustellen oder vorhandene Controls anzupassen. Dazu zeigte er zunächst
den prinzipiellen Aufbau von JavaFX-Controls, welche Interfaces und Dateien zu einem Control gehören und wie diese
zusammenhängen. Allein dieser Einblick war für mich als Entwickler schon sehr spannend und lehrreich.
Als praktisches Beispiel nutzte er ein Control, welches eine LED-Leuchte darstellen sollte. Zum Erstellen der Grafiken
benutzte er ein Vektorgrafikprogramm, welches SVG exportieren konnte. Die SVG-Datei convertierte er mit einem speziellen
Tool in ein Format, welches direkt von JavaFX dargestellt werden kann und benutzte dieses als grafische Grundlage seines
Controls. Anschließend musste noch die Logik des Controls implementiert werden, was er natürlich mit JavaFX-Bindings
umsetzte.
OpenDolphin
Dierk König hat in seinem Vortrag das von ihm mitentwickelte Framework OpenDolphin
vorgestellt. OpenDolphin ermöglicht es, eine Anwendung nach dem Shared
Presentation-Model Muster zu entwickeln. Dabei wird das
Presentation-Model, also sämtliche Daten, die die Benutzeroberfläche beschreiben, auf einem Server gehalten. Die
Oberfläche des Clients verbindet sich mit dem Server und bindet sich direkt an dieses Presentation-Model. Serverseitige
Änderungen an diesem Model sind dann unmittelbar auch auf Clientseite sichtbar. Das gleiche gilt äquivalent auch für
Änderungen des Clients, die sofort zum Server synchronisiert werden.
Werden mehrere Clients mit dem Server verbunden, wird dadurch die UI der Clients untereinander ebenfalls synchron
gehalten.
Dies war für mich auch der Hauptgrund, den Vortrag zu besuchen, da dieses ein ähnlicher Anwendungsfall ist, für den
meine Arbeitskollegen und ich auch unser Framework SynchronizeFX erstellt
haben. In unserer Applikation kommt es ebenfalls auf eine Synchronisierung der UI zwischen mehreren Instanzen an.
Im Detail betrachtet hat OpenDolphin jedoch einen anderen Ansatz. Es lässt sich zwar mit JavaFX verbinden, arbeitet
intern jedoch mit einer eigenen Bindings-Implementierung, während unser Framework ausschließlich mit JavaFX-Bindings
arbeitet.
Während bei unserem Framework der Hauptaugenmerk auf eine einfache Integration in JavaFX-Anwendungen lag, sieht
OpenDolphin eines seiner wesentlichen Ziele darin, die leichte Austauschbarkeit von UI-Technologien zu unterstützen. Da
beim Shared-Presentation-Model die einzige Verbindung zwischen Client und Server das gemeinsame Datenmodell ist, lässt
sich dieses Ziel vergleichsweise gut erreichen.
In der Demo hat er ein Beispiel vorgeführt, bei dem eine JavaFX-Anwendung und eine HTML5/JavaScript-Anwendung
miteinander synchronisiert waren und jeweils die geänderten Daten des anderen Clients anzeigen konnten.
JSF / CDI
Neues aus JavaServer Faces 2.2
In diesem Vortrag hat Andy Bosch über Neuerungen im neuen JavaServer Faces Standard 2.2 berichtet. Er hat dabei 4
wichtige Haupt-Features im Detail erklärt und weitere Nebenfeatures genannt.
Die 4 "Big Ticked Features", wie er es nannte, sind:
HTML5 Support
Wie der Name vermuten lässt, handelt es sich hierbei um eine bessere Integration von HTML5-Features in JSF. Zwar war es
auch bisher schon möglich, mit JSF HTML5-Dokumente auszuliefern und auch die neue HTML5-Tags zur semantischen
Strukturierung von Webseiten ließen sich ohne weiteres benutzen.
Probleme gab es jedoch z.B. mit den von HTML5 definierten data-* Attributen, mit denen in HTML5 jedem Element beliebige
Meta-Informationen mitgeliefert werden können. Dies soll im neuen JSF besser unterstützt werden.
Resource Library Contracts
Für JSF 2.2 war ursprünglich geplant, Multi-Templating zu unterstützen, d.h. es sollte möglich sein, mehrere Themes für
eine Anwendung zu definieren und einfach, auch zur Laufzeit, auszutauschen. Ideen eines Marketplaces, auf dem Templates
und Themes gehandelt werden könnten, standen im Raum. Letztlich hat sich jedoch gezeigt, dass diese Ideen nicht alle in
der gesetzten Zeit umsetzbar waren. Gewissermaßen eine abgespeckte Version ist nun unter dem Namen "Resource Library
Contracts" im neuen JSF 2.2 Standard enthalten.
Mit Resource Library Contracts wird definiert, dass in einer JSF-Anwendung unter 'META-INF/contracts' Verzeichnisse
angelegt werden können, die einem Template entsprechen. In diesem Verzeichnis sollen alle zum Template gehörenden
Dateien untergebracht werden, also XHTML-, CSS-, JavaScript- und sonstige Dateien.
Es wird weiterhin ein gewisser Formalismus definiert, welchen Standards diese Templates folgen sollten, damit ein
einfaches Austauschen auch zur Laufzeit möglich ist. Dieser Formalismus ist allerdings nicht besonders streng, weshalb
nicht garantiert werden kann, dass das Austauschen ohne Anpassung funktioniert.
Letztlich ist es trotzdem die Aufgabe des Entwicklers, sicherzustellen, dass bestimmte Template-Abschnitte vernünftige
Bezeichner besitzen, die in allen Templates identisch sein müssen, damit Elemente ausgetauscht werden können.
Faces Flows
Mit Faces Flows soll es in Zukunft einfacher werden, Seiten zu implementieren, die eine festgelegte Abfolge besitzen,
wie zum Beispiel Wizards, Bestellprozesse oder ähnliches.
Dafür wird ein neuer CDI-Scope FlowScope definiert, der genauso lange gültig ist, wie die Seiten des Flows angezeigt
werden. Die Definition, welche Seiten zu einem Flow gehören, soll dabei deklarativ erfolgen, d.h. die einzele Seite
weiss nicht unbedingt, dass sie zu einem Flow gehört. Dies soll die Wiederverwendbarkeit erhöhen.
Neue JSF-Tags ermöglichen ausserdem die detailierte Steuerung des Flows z.B. mittels Bedingungen/Switch Anweisungen und
der Definition eines Start- und Ende-Punkts.
Stateless Views
Das "Stateless Views"-Feature wurde von Andy Bosch im Vortrag nicht sehr euphorisch vertreten. Er machte eher den
Eindruck, dass dieses Feature nicht wirklich wichtig oder sinnvoll wäre. Es geht darum, bestimmte Views zu definieren,
die keinen serverseitigen Zustand besitzen. Das Ziel dahinter ist, die Performance und den Speicherverbrauch zu
minimieren.
Andy hatte jedoch bezweifelt, dass Stateless-Views dazu beitragen können, diese Ziele nennenswert voranzubringen, da
schon der Partial-State-Saving-Mechanismus, der bei JSF 2 Einzug gehalten hat, den zu speichernden und übertragenden
Zustand auf ein nötiges Minimum reduziert.
Hier die gesamte Feature-Übersicht JSF 2.2.
Apache Deltaspike
Apache Deltaspike ist eine Sammlung von Erweiterungen für "Contexts and Dependency
Injection" (CDI). Es ist aus den Projekten Seam 3 und
Apache CODI hervorgegangen und soll diese beerben. Im Vortrag von Mark
Stuberg wurde das Projekt vorgestellt und einige Beispiele gezeigt.
Beyond PrettyFaces - Einführung in Rewrite
Christian Kaltepoth stellte in seinem Vortrag das Framework Rewrite vor, welches aus
dem JSF-Framework PrettyFaces hervorgegangen ist. PrettyFaces hatte mir schon in
einigen JSF-Projekten gute Dienste geleistet, weshalb es schön war, einmal direkt von einem der Entwickler einen
Einblick zu bekommen.
PrettyFaces ist eine Bibliothek für JavaServer Faces, die einen URL-Rewrite-Mechanismus bereitstellt, um die URLs, die
eine JSF-Anwendung benutzt, nach den Wünschen des Entwicklers anzupassen. Ziel ist es, die teils langen und "hässlichen"
URLs, die JSF von Haus aus nutzt, durch hübsche und kurze URLs zu ersetzen. Statt
'www.example.org/faces/article/overview.xhtml?articleId=1234' könnte dann z.B. die URL 'www.example.org/articles/1234'
benutzt werden. Damit wird gleichzeitig die verwendete UI-Technologie ein wenig versteckt. Vor allem aber können so
Links erzielt werden, die sich als Bookmarks vernünftig speichern lassen.
"Rewrite" setzt dieses Ziel fort. Es wurde aus dem ursprünglichen Framework PrettyFaces herausgelöst und kann als
Nachfolger verstanden werden. Rewrite versteht sich nicht mehr nur als Erweiterung für JavaServer Faces sondern als
allgemeines URL-Rewriting-Framework für Java. Die Unterschiede, die auch im Vortrag gezeigt wurden, betreffen vor allem
die Art und Weise der Konfiguration. Bei PrettyFaces hat der Entwickler die Wahl zwischen einer XML-Konfigurationsdatei
und Annotationen direkt an den JSF-ManagedBeans. Da die letztere Variante aber sehr unübersichtlich ist und ein
zentraler Ort zur Übersicht über alle Rewrite-Regeln vorteilhaft ist, wurde bei uns in Projekten immer die
XML-Konfiguration eingesetzt. Diese hat jedoch auch ihre Nachteile, vor allem die geringe Flexibilität, mit der Regeln
geschrieben werden können.
Bei Rewrite wird dieses Problem gelöst, in dem eine Fluent-API zur Beschreibung der Regeln mitgeliefert wird. Damit kann
der Entwickler seine Regeln in Java-Code formulieren und ist bei Refactorings abgesichert. Er kann aber trotzdem alle
Regeln an einer zentralen Stelle im System sammeln oder aber auf verschiedene Klassen aufteilen, wenn das notwendig sein
sollte. Der Entwickler hat also die volle Kontrolle.
Aus meiner Sicht ist dieser Ansatz sehr vielversprechend und sollte unbedingt im Auge behalten werden.
Slides
JSF Performance
Im Vortrag von Thomas Asel wurden einige typische Performance-Probleme von JavaServer Faces aufgezeigt und mögliche
Lösungen analysiert.
Das potentielle Problem von JSF ist, dass auf Serverseite zu jedem Request ein relativ umfangreicher Lifecycle
durchlaufen wird, bei dem ein Komponenten-Baum der UI aufgebaut und bearbeitet wird.
Es stellte sich heraus, dass die Größe des Komponentenbaums einen entscheidenden Einfluss auf die Performance der
Applikation hat. Je größer der Komponentenbaum, desto länger braucht JSF für die Abarbeitung des Lifecycles.
Interessanter Weise gibt es hier offensichtlich starke Unterschiede zwischen den beiden JSF-Implementierungen. Bei der
Referenzimplementierung Mojarra kann man einen exponentiellen Zusammenhang zwischen der Größe des Komponentenbaums
und der Verarbeitungsdauer feststellen, was dazu führt, dass bei relativ großen UI's Mojarra recht lange braucht. Die
alternative Implementierung Apache MyFaces zeigt ein anderes Verhalten. Zum einen ist die Geschwindigkeit
durchgehend deutlich höher als bei Mojarra. Zum anderen ist hier ein Linearer Zusammenhang zwischen Größe des UI und
Verarbeitungsdauer zu sehen, was dazu führt, dass der Geschwindigkeitsvorteil umso größer ausfällt, je größer der
Komponentenbaum ist.
Aus diesen Erfahrungen können zwei Bausteine zur Verbesserung der Performance gewonnen werden:
-
Wenn möglich, sollte Apache MyFaces als Implementierung gewählt werden. Dies ist allerdings nicht immer möglich.
Zwar kann bei allen Enterprise-Servern die JSF-Implementierung getauscht werden, oft sind hier jedoch praktische
Einschränkungen durch Support-Verträge gegeben, die verfallen wenn der Server umkonfiguriert wird.
-
Der Entwickler sollte unabhängig von der Implementierung die Größe des Komponentenbaums möglichst klein halten. Vor
allem bei Custom-Komponenten ist Vorsicht geboten. Zum Beispiel sollten reine Wrapper-Komponenten vermieden werden.
Neben der reinen JSF-Verarbeitung existieren noch weitere Stellen, bei denen auf die Performance Einfluss genommen
werden kann. Vor allem die Übertragung von zahlreichen großen Dateien zum Client nimmt viel Zeit in Anspruch. Um diesem
Problem zu begegnen, können JavaScript- und CSS-Dateien zunächst zu je einer Datei zusammengefasst werden und diese
kombinierten Dateien "minifiziert" werden. Es wurde jedoch gezeigt, dass dabei auch Vorsicht geboten ist und umsichtig
geplant werden muss, um tatsächlich einen Vorteil zu erlangen. Würde man z.B. sämtliche JavaScript-Dateien des gesamten
Projekts zu einer einzelnen Datei kombinieren. Es wird jedoch in der Regel nicht überall sämtlicher Code benötigt
sondern nur ein Teil davon. Es bietet sich hier z.B. an, Bibliotheken wie jQuery und natürlich jsf.js, die
JavaScript-Library von JSF selbst, zu einer Datei zusammenzufassen, da dieser Code in der Regel überall gebraucht wird.
Wichtig ist auch die Integration der Kombinierungs- und Minifizierungsschritte in den Build-Prozess, da man während der
Entwicklung ja die Quelltexte in einem vernünftig lesbarem Format erhalten möchte. Im Vortrag wurden einige Tools
genannt, die diese Vorgänge z.B. in einen Maven-Build-Schritt erledigen.
Weiterführende Informationen zu den Performancemessungen sind
hier zu finden.