Eclipse Wiki Weblog

All | General | Java | Eclipse | Wikipedia | AJAX(GWT)
20060726 Wednesday July 26, 2006

GWT Applikation entwickeln und deployen in Tomcat

Für die Projekte MathEclipse.org (Online AJAX Calculator) und JTidy.de (HTML to Wiki Converter) habe ich jetzt eine Version auf den Server gestellt, die auf dem Google Web Toolkit basiert.
Das Coding des MathEclipse Projekts findet man im CVS Modul org.matheclipse.gwt.

Nachfolgend habe ich einige Punkte aufgeschrieben, die mir beim Entwickeln und Deployen besonders aufgefallen sind.

Contents
  1. Entwickeln der Anwendung
    1. Aufteilung des Namensraums
    2. Der GWT RPC Mechanismus
    3. Clientseitige Dateien erzeugen
    4. JavaScript Fehlersuche
    5. Neue Features
  2. Deployen der Anwendung
    1. Tomcat Server Einstellungen
    2. JAR Dateien auf den Tomcat Server kopieren
    3. URL Unterschiede im Hosted Mode und im Tomcat Server

Entwickeln der Anwendung

Aufteilung des Namensraums

In der org.matheclipse.gwt/calc.gwt.xml Datei wird der Servlet Pfad /me definiert:

<module>

	<-- <Inherit the core Web Toolkit stuff.                  -->
	<inherits name='com.google.gwt.user.User'/>

	<-- <Specify the app entry point class.                   -->
	<entry-point class='org.matheclipse.gwt.client.Calc'/>
	
	<servlet path='/me' class='org.matheclipse.gwt.server.CalcServiceImpl'/>
</module>

Der GWT RPC Mechanismus

In einer GWT Anwendung benutzt man den RPC Mechanismus um Daten vom Server nachzuladen (im erzeugten JavaScript Code wird dabei, wie sonst auch bei AJAX Anwendungen üblich, ein XMLHttpRequest abgesetzt). Um einen RPC zu erstellen muss man 2 Java Interfaces und eine Klasse definieren.

Zuerst einmal ein Java Interface für den Evaluierungs Service. Dieses Interface muss das GWT RemoteService Interface erweitern.

package org.matheclipse.gwt.client;

import com.google.gwt.user.client.rpc.RemoteService;

public interface CalcService extends RemoteService {
	public String evaluate(String expression, String function, int counter);
}

Das zweite Interface für den Client wird benutzt um die Service Methode asynchron aufzurufen.

package org.matheclipse.gwt.client;

import com.google.gwt.user.client.rpc.AsyncCallback;

interface CalcServiceAsync {
	public void evaluate(String expression, String function, int counter, AsyncCallback callback);
}

GWT benutzt dabei ein Callback Interface AsyncCallback, dass die Antwort des Servers für unsere Anwendung "aufbereitet". Als Namenskonventiion verlangt GWT, dass das Kürzel "Async" an den Namen des Service Interfaces CalcService angehängt wird.

Diese 2 Interfaces sind Teil des Java Codes, der benutzt wird, um den JavaScript Code zu erzeugen.

Als letzten Schritt implementieren wir eine Servletklasse, die das CalcService Interface implementiert. Diese Klasse muss RemoteServiceServlet erweitern, die wiederum eine von der Standard Java Klasse HttpServlet abgeleitete Klasse ist. Die Servlet Klasse muss später mit auf den Tomcat Webserver deployed werden.

package org.matheclipse.gwt.server;
...

...
public class CalcServiceImpl extends RemoteServiceServlet implements
		CalcService {
	public String evaluate(String expression, String function, int counter) {
...

...
	}

...

...

}

Clientseitige Dateien erzeugen

In der Eclipse Entwicklungsumgebung kann man das Programm Calc-compile.cmd starten. Dadurch wird im Unterordner /org.matheclipse.gwt/www/org.matheclipse.gwt.Calc aus den Java Dateien der entprechende komprimierte JavaScript Code erzeugt.

JavaScript Fehlersuche

Die ersten Versionen meiner Anwendung hatten im Firefox 1.5 einen Fehler (unter IE6.0 im GWT "hosted mode" funktionierte die Anwendung hingegen tadellos). Dabei wurde eine nichtssagende Fehlermeldung herausgegeben:

 uncaught exception: com.google.gwt.core.client.JavaScriptException:
 JavaScript TypeError exception: seb has no properties

Als erste Massnahme um das Problem einzukreisen hatte ich mir deshalb Firebug installiert. Mit dem Feature Spy on XMLHttpRequest traffic konnte man zumindest erkennen, dass das Problem nicht auf dem Server liegt, weil kein XMLHttpRequest mehr abgesetzt wurde.
(dies Ergebnis war auch zu erwarten, weil die Anwendung ja unter IE6 funktionierte ;-) )

Als nächsten Schritt habe ich dann in dem Calc-compile.cmd Skript die Option -style pretty gesetzt, damit der GWT Compiler den JavaScript Code in lesbarer Form erzeugt. Jetzt konnte man im Firebug Debugger erkennen, dass in der Funktion _$__evaluate ein Call zum serialisieren des RPC requests _$writeObject(_stream, _function) den Fehler erzeugte. In der Variablen _function stand dabei der Wert "eval". Ich vermute mal das Firefox mit der Serialisierung nicht klarkommt, da "eval" unter JavaScript ein Schlüsselwort ist? Nach der Umbenennung der Funktion von "eval" nach "$eval" funktionierte das Ganze dann auch unter Firefox.

Der Fehler lässt sich im übrigen mit einem Firefox 1.5 immer noch reproduzieren, wenn man in der MathEclipse Textarea nur das Wort "eval" eingibt und dann den Button Symbolic Eval drückt.

Neue Features

Die MathEclipse Anwendung hat diese neuen Features aufgrund der Verwendung des GWT bekommen:

Deployen der Anwendung

Tomcat Server Einstellungen

Das Web-Application Verzeichnis lautet tomcat/webapps/me

JAR Dateien auf den Tomcat Server kopieren

Alle benötigten *.jar Dateien der Webanwendung müssen wie üblich in das tomcat/webapps/me/WEB-INF/lib Verzeichnis kopiert werden.

Aus der von Google mitgelieferten gwt-user.jar müssen alle javax.* Klassen entfernt werden, da diese mit den vom Tomcat verwendeten javax.* Klassen kollidieren (dies habe ich einfach mit einem ZIP Tool gemacht). Nachtrag: ab GWT Version 1.1.0 wird die Datei gwt-servlet.jar mitgeliefert, so dass man jetzt die javax.* Klassen nicht mehr entfernen muss.

Alle Dateien die unterhalb von /org.matheclipse.gwt/www/org.matheclipse.gwt.Calc liegen, per FTP auf den Tomcatserver in das tomcat/webapps/me Verzeichnis kopieren.

URL Unterschiede im Hosted Mode und im Tomcat Server

Probleme können durch die verschiedenen URL Kontexte in denen GWT jeweils benutzt wird entstehen. Wenn die Anwendung in Tomcat deployed wurde liefert GWT.isScript() den Wert true zurück im hosted mode hingegen den Wert false:

		ServiceDefTarget target = (ServiceDefTarget) service;
		if (GWT.isScript()) {
			String url = GWT.getModuleBaseURL();
			url += "/me";
			target.setServiceEntryPoint(url);
		} else {
			target.setServiceEntryPoint("/me");
		}

In der webapps/me/WEB-INF/web.xml stehen die folgenden Angaben:

<servlet>
<servlet-name>CalcServiceImpl</servlet-name>
<servlet-class>org.matheclipse.gwt.server.CalcServiceImpl</servlet-class>
<load-on-startup/>
</servlet>

<servlet-mapping>
<servlet-name>CalcServiceImpl</servlet-name>
<url-pattern>/me</url-pattern>
</servlet-mapping>

Posted by axelclk ( Jul 26 2006, 06:11:35 PM CEST ) Permalink Comments [0]

Kalender

Links

del.icio.us Tag Cloud

RSS Feeds

Suche

Navigation

Referenziert von