Grüntee vs. Rentier

GXT oder Vaadin? Zwei Web-Frameworks im Vergleich

Holger Herrmann

© shutterstock.com/martinhlavacek79

Thin-Client-Architektur und die wachsende Beliebtheit von Cloud-Lösungen sind nur zwei Aspekte, die Web Application Frameworks immer beliebter werden lassen. Für einen Großteil dieser Frameworks muss der Entwickler das immer noch bei vielen unbeliebte JavaScript beherrschen. Einige aber umgehen dieses Problem und bauen auf dem Google Web Toolkit (GWT) auf. In diesem Artikel stelle ich zwei dieser Frameworks nebeneinander: GXT von der Firma Sencha und Vaadin vom gleichnamigen finnischen Unternehmen. 

Das Prinzip des Google Web Toolkits ist es, dass neben dem Servercode auch der komplette Client-Code in Java geschrieben werden kann. Bevor die Anwendung gestartet werden kann, wird dieser Code mithilfe des GWT Compilers in Java Scripts übersetzt. Natürlich muss der GWT Compiler den jeweils verwendeten Befehlssatz kennen. Das hat zur Folge, dass nicht beliebige Bibliotheken für den Client verwendet werden können, sondern nur diejenigen, die der Compiler übersetzen kann. Eine genaue Aufstellung der unterstützten Klassen findet man in der GWT-Dokumentation.

Die Firma Sencha aus den USA hat mit ihrem Produkt „Sencha GXT“ ein leistungsstarkes Web-Framework auf Basis von GWT auf dem Markt. Im Wesentlichen handelt es sich dabei um Erweiterungen der GWT-Komponenten, die in den Client-Code eingebunden werden. Dabei wird der Schwerpunkt auf die Performance und die Styles der Widgets gelegt.

Eine Übersicht über die Architektur einer GXT-Anwendung gibt Abbildung 1.

Abb. 1: Anwendungsarchitektur Sencha GXT

Sie unterscheidet sich zunächst nicht von einer „reinen“ GWT-Anwendung. Lediglich im Browser-Teil ist die Ergänzung „GXT“ ersichtlich.

Im Rahmen von GWT (und damit auch GXT) gibt es die Möglichkeit, den Client-Code in der IDE zu debuggen. Dazu wird die Anwendung im so genannten „Development Mode“ gestartet. Dieser bewirkt, dass der Code erst zur Laufzeit in JavaScript übersetzt wird. Das hat zwar eine deutliche Performancebeeinträchtigung zur Folge. Der Client-Code kann so aber wie „normaler“ Java-Code im Debugger behandelt werden.

Bei Vaadin liegt der Schwerpunkt etwas anders. Der Begriff „Vaadin“ bezeichnet sowohl das Unternehmen als auch das Web Application Framework. Er bezeichnet im Finnischen ein weibliches Rentier. Als Logo wird eine geschweifte Klammer, gefolgt von einer spitzen Klammer, verwendet: }>. Dreht man dieses Zeichen um 90 Grad nach rechts, so erhält man einen stilisierten Rentierkopf.

Im „Book of Vaadin“, der umfassenden Dokumentation von Vaadin, findet sich auch eine Abbildung zur Architektur (vgl. Abbildung 2).

Abb. 2: Anwendungsarchitektur Vaadin

Der konzeptionelle Ansatz in Vaadin unterscheidet sich von GXT; dort werden mehr Aktionen im Browser behandelt. Bei Vaadin hingegen werden mehr Server-Calls durchgeführt. So werden auch die Events von GUI-Komponenten auf Serverseite ausgeführt. Das erhöht zwar den Kommunikationsaufwand zwischen Browser und WebServer. Auf der anderen Seite muss der GWT Compile in diesem Fall nicht durchgeführt werden. Auch das Debuggen gestaltet sich so einfacher, weil kein Client-Code selbst geschrieben werden muss. Ist das aber trotzdem erwünscht, dann ist auch das Erstellen von Client-Komponenten, so genannten „Widget Sets“, mit Vaadin möglich.

Beispielanwendungen bauen

Um die ersten Schritte mit den beiden Frameworks zu zeigen, habe ich für den Artikel für das Java Magazin, der in der Ausgabe 3.2015 erscheinen wird, mithilfe der von den Herstellern gegebenen Tutorials jeweils eine Beispielanwendung implementiert. Sie soll eine einfache Anwendung zur Bestätigung einer Sicherheitsunterweisung darstellen und lediglich aus drei Komponenten bestehen: 1. einem Textfeld für die Erfassung des Benutzernamens, 2. einem Datumsfeld zur Erfassung des Datums der Kenntnisnahme und 3. einem Button zur Durchführung der Bestätigung. Als zusätzliche Validierung soll hinterlegt werden, dass das erfasste Datum nicht in der Zukunft liegt.

Die Codierung mit GXT

Ausgangspunkt für die Implementierung mit GXT ist die Dokumentation „Getting started with GXT“ von der offiziellen Homepage von Sencha. Für die Entwicklung mit Eclipse ist das GWT Plug-in notwendig. Dieses ist für meine Eclipse-Version Luna noch nicht vorhanden. Die Installation und Verwendung des Plug-ins für Kepler funktioniert aber problemlos. Nach der Installation des Plug-ins kann gemäß der Beschreibung ein GWT-Projekt angelegt werden, was ebenfalls keine Schwierigkeiten mit sich bringt.

Schwieriger wird es, wenn der erstellte Client-Code gestartet und getestet werden soll, wobei der Development Mode zum Einsatz kommt. Die Funktionsfähigkeit ist dann stark Browser-abhängig:

Erstens: Beim Starten der Anwendung in Chrome werde ich aufgefordert, das GWT Developer Plug-in zu installieren. Das funktioniert problemlos, und die erstellte Beispielanwendung läuft nach wenigen Momenten.

Zweitens: Firefox meldet ebenfalls, dass das GWT Developer Plug-in notwendig ist. Dieses ist für aktuelle Firefox-Versionen aber nicht verfügbar, und hier gibt es auch keinen Workaround: Um die Anwendung im Firefox ansehen zu können, muss sie immer vorher durch den GWT Compiler gelaufen sein. Das kostet Zeit und man verliert die Möglichkeit des Debuggens.

Drittens: Der Internet Explorer 11 bietet mir eine Besonderheit. Auch für ihn ist natürlich das Plug-in notwendig. Angeboten wird aber die Version für Firefox (IE 11 gibt sich intern als Firefox aus). Damit kommt man natürlich nicht ans Ziel, es gibt aber einen Trick: Öffnet man die Developer Tools (F12), so findet man im Menü „Emulation“ den Dokumentenmodus (Abbildung 3). Diesen ändert man auf „IE10“, und nach erneutem Laden der Seite kann das richtige Plug-in installiert werden. Nach dem Bestätigen einer Sicherheitsabfrage wird die Seite dann auch korrekt geladen. (Der Dokumentenmodus kann auf Edge zurückgesetzt werden.)

Abb. 3: Um das GWT Developer Plug-in im IE11 installieren zu können, wendet man einen Trick an

Um zu einer „richtigen“ GXT-Anwendung zu kommen, muss jetzt nur noch die entsprechende Bibliothek in das Projekt eingebunden werden (GXT gibt es in der 30-Tage Evaluation Version auf der Sencha-Homepage). In der GWT-Konfigurationsdatei muss außerdem das GXT-Modul eingebunden werden (vgl. Listing 1).

<module rename-to='sicherheitsunterweisung'>
  ...
  <!-- inherit GXT module -->
  <inherits name='com.sencha.gxt.ui.GXT' />
  ...
</module>

Für die Elemente in meiner Beispielanwendung können jetzt die GXT-Komponenten wie „normale“ GWT-Komponenten verwendet werden. Einstiegspunkt der Anwendung ist die Methode onModuleLoad(). Dort implementiere ich beispielsweise das Textfeld mit Beschriftung und füge es der (leicht angepassten) HTML-Seite hinzu (Listing 2).

LabelToolItem nameLabel = new LabelToolItem("Name:");
final com.sencha.gxt.widget.core.client.form.TextField nameField = 
  new com.sencha.gxt.widget.core.client.form.TextField();

RootPanel.get("nameLabel").add(nameLabel);
RootPanel.get("nameField").add(nameField);

Die Beispielanwendung von GXT liefert sowohl eine Feldvalidierung auf Client-seite (FieldVerifier) als auch die Implementierung eines RPCs (GreetingService) mit. Möchte man nun z. B. eine Prüfung des erfassten Datums implementieren, kann das ganz einfach Client-seitig gemacht werden; ein „Server Roundtrip“ ist in diesem Fall nicht notwendig. Dafür erhält der Button für das Abschicken der Bestätigung einen DomHandler, mit dem das ClickEvent abgefangen wird (Listing 3).

sendButton.addDomHandler(new ClickHandler() {
  public void onClick(ClickEvent event) {
    String dateString = dateField.getCell().getText(dateField.getElement());
    boolean dateOK = FieldVerifier.isValidDate(dateString);
    if (!dateOK) {
      ...
    }
  }
}

Wird der RPC durchgeführt, geschieht das – wie bei allen GWT-Projekten – mittels AJAX-Technologie. Bei erfolgreichem Aufruf kann dann ein entsprechender Hinweis ausgegeben werden (Listing 4).

String textToServer = nameField.getText();
securityService.confirmReading(textToServer, new AsyncCallback() {
    public void onFailure(Throwable caught) { }

        public void onSuccess(String result) {
          MessageBox msgBox = new MessageBox("Sicherheitsunterweisung", result);
          msgBox.show();
        }
});

Sicherheit auch mit Vaadin

Ausgangspunkt für die Demo-Anwendung ist das Kapitel 2 des „Book of Vaadin“, das auch in einer sehr handlichen gedruckten Ausgabe erhältlich ist. Die empfohlene „tool chain“ von Vaadin ist:

Windows, Linux oder Mac OS X

– Sun Java 2 Standard Edition (JDK 1.6 oder höher)

– Eclipse IDE für Java EE developers

– Apache Tomcat 7.0 (Core)

– Mozilla Firefox browser

– Optional: Firebug debug tool

– Vaadin Framework

Um in Eclipse mit Vaadin arbeiten zu können, ist neben dem Vaadin-Plug-in auch das IvyDE-Plug-in notwendig. Es zeigte sich im weiteren Verlauf, dass es damit zu den größten Schwierigkeiten beim Bauen der Beispielanwendung kommt. Möchte man die Anwendung wie in der Referenz beschrieben erstellen, tauchen im letzten Schritt Fehlermeldungen von eben diesem IvyDE-Plug-in auf (Abbildung 4).

Abb. 4: Kein Erfolg mit Eclipse Luna und der letzten stabilen Version des Ivy-Plug-ins

Die Fehlermeldung ist Folge daraus, dass keine gültige ivy.xml erstellt werden konnte. Dadurch können die notwendigen Abhängigkeiten nicht aufgelöst werden, und es werden auch keine Vaadin-Bibliotheken in das Projekt eingebunden. Die Lösung des Problems findet sich in der Aktualisierung des Plug-ins auf das letzte erfolgreiche Build. Hiermit können zwei Items des Plug-ins aktualisiert werden.

Nachdem ich beim Einrichten des Servers das Projekt bereits verknüpft habe, steht die Anwendung nach Serverstart schon unter http://localhost:8080/sicherheitsunterweisung zur Verfügung.

Die Implementierung der einzelnen Komponenten ist jetzt – wie bei GXT – recht einfach: Auch die Widgets von Vaadin können analog der Komponenten von GWT verwendet werden. Die erste Methode, die bei einer Vaadin-Anwendung ausgeführt wird, ist die Methode init(), so dass ich dort das Layout zusammenbaue. Ich füge also die Überschrift, ein Textfeld, ein Datumsfeld sowie einen Button in die Seite ein (Listing 5).

@Override
protected void init(VaadinRequest request) {

      final VerticalLayout layout = new VerticalLayout();
    layout.setMargin(true);
    setContent(layout);

    // Überschrift
    Label label = new Label("Sicherheitsunterweisung");
    label.addStyleName("header-style");
    layout.addComponent(label);

    // Textfeld
        HorizontalLayout hl = new HorizontalLayout();
    hl.setSpacing(true);
    layout.addComponent(hl);
    FormLayout fl = new FormLayout();
    final TextField nameField = new TextField("Name:");
    fl.addComponent(nameField);

    // Datumsfeld
    final DateField dateField = new DateField("Erfassungsdatum:");
    fl.addComponent(dateField);
    hl.addComponent(fl);

    layout.addComponent(new HorizontalLayout());

    // Abschicken-Button
    Button send = new Button("Abschicken");
    send.addClickListener(new Button.ClickListener() {
      public void buttonClick(ClickEvent event) {

        if (!validDate(dateField.getValue()))
          Notification.show("Das Datum darf nicht in der Zukunft liegen.");
            else
          Notification.show("Vielen Dank für die Bestätigung, " + nameField.getValue());
           }
	});
	layout.addComponent(send);
}

Da bei Vaadin die Browser Events direkt auf den Server geschickt werden, ist der Development Mode für das Debuggen nicht notwendig.

Zusammenfassung und Fazit

Sowohl mit Vaadin als auch mit GXT kann man leistungsstarke Webapplikationen bauen. Bei GXT liegt der Schwerpunkt mehr auf der Client-Entwicklung; das Ziel bei Vaadin ist, keine eigenen Widgets bauen zu müssen. Weil das aber durchaus manchmal gewünscht ist, gibt es auch hier die Möglichkeit, das zu tun und ein eigenes „Widget Set“ zu erzeugen.

Im Praxistest tauchten (in der gewählten Konstellation der technischen Komponenten) bei beiden Frameworks Probleme auf. Diese lagen allerdings bei beiden nicht an den Komponenten der Unternehmen selbst: Bei GXT gab es Schwierigkeiten mit dem Debuggen im Development Mode: Nicht für alle Browser sind die richtigen Plug-ins verfügbar. Abhilfe könnte der neu entstandene „Super Dev Mode“ schaffen. Bei Vaadin hatte ich besonders Schwierigkeiten bei der Anlage von neuen Projekten und der damit verbundenen Auflösung der Abhängigkeiten über Ivy. Hier war das Ivy-Plug-in für meine Eclipse-Version nicht richtig lauffähig; die Lösung lieferte ein Update des Plug-ins auf die aktuellste (Entwicklungs-)Version (2.5.0.alpha).

Weil nicht alle denkbaren GUI-Komponenten im Kern von Vaadin enthalten sein können, gibt es zahlreiche Add-ons, die von der Community entwickelt werden und auf der Homepage zum Download bereitstehen. Die Community ist bei Vaadin sehr aktiv und erweitert damit die Kernfunktionalität des Produkts. Dem kommt das gewählte Lizenzmodell entgegen: Vaadin ist Open Source unter der Apache-2.0-Lizenz erhältlich. Sencha GXT ist lediglich für Open-Source-Projekte kostenfrei (GPLv3-Lizenz), für Unternehmensanwendungen ist eine separate Lizenz erforderlich. Diese enthält neben der Anwendung auch den Premium Support und kostet im ersten Jahr 4.635 $ (für bis zu fünf Entwickler).

Die Wahl des „richtigen“ Frameworks hängt letztlich immer von den gegebenen Voraussetzungen ab: Sollen überwiegend eigene Komponenten entwickelt werden und möglichst viel Funktionalität im Browser ablaufen, bietet sich Sencha GXT an. Liegt der Schwerpunkt auf schneller und konsistenter, Server-seitiger Entwicklung mit einem Open-Source-Framework, ist Vaadin die richtige Wahl.

Aufmacherbild: reindeer in Norway von shutterstock.com / Urheberrecht: martinhlavacek79

Geschrieben von
Holger Herrmann
Holger Herrmann
Holger Herrmann beschäftigt sich seit über zehn Jahren mit Java, seit einigen Jahren mit Schwerpunkt auf Technologien bei Webanwendungen. Seit 2011 arbeitet er als Entwickler und Softwarearchitekt bei Rödl&Partner.
Kommentare

Hinterlasse einen Kommentar

1 Kommentar auf "GXT oder Vaadin? Zwei Web-Frameworks im Vergleich"

avatar
400
  Subscribe  
Benachrichtige mich zu:
Michael
Gast

Ich find’s schade, dass beim Listing 5 die imports fehlen. Konnte die meisten händisch einsetzen, aber für Methode validDate(dateField.getValue()) habe ich noch nichts gefunden…