Jax 2013

javajavaeejsfjavafx

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:

  1. 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.

  2. 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.