Mittwoch, 6. Mai 2009

GWT Lernen: Verwendung von H1, H2, etc. für Überschriften

GoogleDesktopPhotosPluginWallpaper Beim Aufbau meiner Seiten mit dem GWT möchte ich die üblichen HTML Tags H1-H6 verwenden. Wie geht das?

Die direkt Verwendung eines Labels funktioniert nicht. Eine Anweisung wie:

this.add(new Label("<h1>Titel</h1>"));

erzeugt im hosted mode die Darstellung

<h1>Titel</h1>

, die Tags werden also quotiert. So steht es auch in der Label Java Doc. Dort findet sich aber auch der Hinweis auf das HTML Widget. Damit lässt sich die Aufgabe lösen. Die Anweisung:

this.add(new HTML("<h1>Titel</h1>"));

erzeugt die gewünschte Darstellung. Berücksichtigen muss man nur, dass man so die Sicherheitsvorteile, die die automatische HTML Quotierung des Labels bietet, verliert.

Dienstag, 5. Mai 2009

Externe Klassen im GWT nutzen

P1090268bIn meiner GWT 1.6 Anwendung nutzen sowohl der client- wie auch der serverseitige Code die gleichen Geschäftsmodellklassen. Diese Klassen liegen allerdings in einem anderen Eclipseprojekt und sind daher nicht ohne weiteres in meinem mit dem Google Plugin angelegten Eclipse GWT Projekt verfügbar. Damit alles rund läuft sind folgende Konfigurationen notwendig:

Eclipse Konfiguration

Simpel: ‘Wie immer’ in den Project Properties den Java Build Path um das Projekt erweitern, in welchem das Geschäftsmodell entwickelt wird (also den CLASSPATH erweitern). Danach kann man sowohl in der client- und serverseitigen GWT Programmierung schon mal die entsprechenden Klassen in Eclipse nutzen.

Generierung des client-seitigen Codes

Das aus meiner Sicht Beste am GWT, nämlich die Übersetzung von Javascript Code aus Java Code, sorgt für eine kleine Komplikation: Der GWT Compiler braucht für alle in der Clientprogrammierung referenzierten Klassen den Quellcode. Ohne Quellcode keine JS Konvertierung und damit keine Clientanwendung. Man findet in der Fehlerausgabe des Hosted Modes Einträge wie den Folgenden, so lange die Geschäftsmodellklassen nicht verfügbar sind:

[ERROR] Line 21: No source code is available for type x.y.z.modell.KlasseXY; did you forget to inherit a required module?

Ähnliche Meldungen erhält man, wenn man in Eclipse das Projekt neu übersetzt:

Compiling module x.y.z.GWTProj
   Refreshing module from source
      Validating newly compiled units
         Removing units with errors
            [ERROR] Errors in 'file:/…/GWTProj/src/x/y/z/client/Modell.java'
               [ERROR] Line 5: The import x.y.z..modell.KlasseXY cannot be resolved

…..

[ERROR] Line 40: Missing code implementation in the compiler

Der Hinweis in der Fehlermeldung auf ein fehlendes inherit führt einen in die Beschreibung der module XML files. Eigentlich hatte ich gehofft, dass es mindestens im Fall von Klassen, die keine Widgets sind, nicht notwendig sein würde mein komplettes Geschäftsmodell mit speziellen module XML files zu durchsetzen. Dafür finde ich aber leider keinen Weg. Musste daher also so vorgehen:

Das Geschäftsmodell befindet sich im Paket org.xy.smod. In diesem Paket gründe ich die neue Modul-XML-Datei SMod.gwt.xml, die folgenden Inhalt hat:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.6.4//EN" "
http://google-web-toolkit.googlecode.com/svn/tags/1.6.4/distro-source/core/src/gwt-module.dtd">

<module rename-to='smod'>

<source path="" />

</module>

Ich lege also ein neues ‘Modul’ an mit dem Namen smod. Die source-Anweisung ist notwendig, damit alle Klassen direkt im Paket einbezogen werden. Ansonsten ist die Datei leer. Insbesondere müssen nicht die sonst üblichen GWT Module wie com.google.gwt.user.User eingebunden werden, auch gibt es natürlich keinen entry-point.

Jetzt muss ich in der Modul-XML-Datei meiner eigentlichen Anwendung nur noch dieses Modul über inherit einbinden. Dazu wird folgende Zeile eingefügt:


<inherits name='org.xy.smod.SMod'/>

Damit sind wir fertig! Zumindest in meiner Umgebung findet der GWT Compiler jetzt die Quellcodes der Geschäftsmodellklassen, die in einem anderen Eclipse Projekt liegen, und kann sowohl die Kompilierung wie auch den Start im hosted mode erfolgreich durchführen.

Hinweis: Eine gute Beschreibung des GWT Compilers im Allgemeinen findet man in den im Internet frei erhältlichen Abschnitt ‘Understand the GWT Compiler’ aus dem Buch GWT in Practice.

Testen der serverseitigen Programmierung / Deployment im Webserver

Sobald man die serverseitige Programmierung testen will bzw. bei der Installation des Anwendungs-WARs in Produktionsserver müssen den RPC Servlets ebenfalls die Geschäftsmodellklassen zur Verfügung stehen. Da es sich hier wieder um eine reine Java Angelegenheit handelt ist nur der Bytecode z. B. in Form eines entsprechenden JARs notwendig. Das Jar packt man ‘wie immer’ in /WEB-INF/lib/ und ist fertig.

Umgang mit java.io.Serializable

P1090074b Hier eine kleine Sammlung von Links zum Thema Serialisierbarkeit in Java, was insbesondere auf die Implementierung des Interfaces Serializable hinausläuft.

Kurzantwort auf  die Frage, wie man eine Java Klasse serialisierbar macht:

  1. Klasse muss Interface Serializable implementieren
  2. Klasse muss eine serialVersionUID enthalten, deren Wert am besten über das im JDK enthaltene Tool servialver  erzeugt wird (dabei ggf. schön die Hinweise zum CLASSPATH beachten und NICHT versehentlich das Source-Verzeichnis adressieren).
    Wenn man Eclipse verwendet, so kann auch die IDE zur Generierung genutzt werden. Hinweise dazu hier.

Die fertige Klasse sieht dann z. B. so aus:

public class SMAbschluss
    implements Serializable {

    static final long 
      serialVersionUID = -689428171468533962L;

….