Fachartikel zur Übersicht
Hot Spots bei der Entwicklung einer RAP-Anwendung
Die Entwicklung von Web-Anwendungen mit dem Eclipse-Framework RAP erfreut sich, vor allem im Umfeld der Eclipse RCP-Gemeinde, wachsender Beliebtheit. Bei der Implementierung einer RAP-Anwendung gibt es jedoch einige Punkte die speziell im Vergleich zur Entwicklung einer RCP-Anwendung beachtet werden müssen. Die signifikantesten Unterschiede sollen in diesem und weiteren Artikeln angesprochen und detailliert betrachtet werden. Im Folgenden werden zuerst die Historie der RAP und daraufhin erste Hot Spots bei der RAP-Entwicklung betrachtet.
Allgemeines zur Rich Ajax Platform
Die Eclipse Rich Ajax Platform (kurz RAP) ist ein Eclipse-basiertes Framework zur Entwicklung von Web 2.0-Anwendungen (Ajax[1]) auf Basis von Java mit starker Annäherung an die Eclipse Rich Client Platform (RCP).
Im Gegensatz zur klassischen Entwicklung von Web-2.0-Anwendungen muss bei der Entwicklung einer RAP-Anwendung keinerlei HTML-, JavaScript- und XML-Programmierung vorgenommen werden. Es wird ausschliesslich in Java programmiert und der entsprechende HTML- und JavaScript-Code wird vom RAP-Framework zur Laufzeit generiert.
Ein weiteres Grundkonzept von RAP ist, dass eine RAP-Anwendung durch wenig Mehraufwand in eine RCP-Anwendung und umgekehrt (RCP → RAP) transformiert werden kann. Man spricht hier von Single-Sourcing [2] für Desktop- und Web-Anwendungen, d.h. es liegt dieselbe Codebasis sowohl für die Web- als auch für die Richclient-Anwendung vor und es sind lediglich Anpassungen in den jeweiligen Konfigurationsdateien, beispielsweise bei den Plugin-Abhängigkeiten, notwendig.
RAP-Historie
RAP wurde von der auf die Entwicklung von Eclipse-Plugins spezialisierten Karlsruher Firma Innopract entwickelt und steht unter der Eclipse Public License als Open Source zur Verfügung [3]. RAP wurde als Eclipse-Projekt im März 2006 vorgeschlagen und im Juni 2006 als solches bestätigt.
RAP liegt momentan in der Version 1.2.2 vor und wird laufend weiter entwickelt. Die nächste Version 1.3 soll als Bestandteil des nächsten jährlichen Eclipse Release-Bundles (Helios) im Juni 2010 veröffentlicht werden.
RAP- und RCP-Historie bei Sybit GmbH
- RCP
- 2006 Entwicklung eines Lagerverwaltungssystems
- 2007 Entwicklung eines Portals zur Crashanalyse
- 2008 Entwicklung Bildimport für ein Bildarchiv
- 2009 Entwicklung eines Angebotsmanager
- RAP
- 2008 Diplomarbeit zur Portierung einer bestehenden RCP-Anwendung (Portal zur PKW-Crashanalyse)
- 2009 Entwicklung eines browser-basierten Bildarchivs mit Recherche- und Administrationsbereich
Die Hot Spots
Auf die folgenden Hot Spots bei der Entwicklung von RAP-Anwendungen wird nun näher eingegangen:
Server-getriggerte Eventbehandlung
Um Änderungen die im Hintergrund, also nicht innerhalb des UI-Threads, erzeugt werden in der Oberfläche anzuzeigen, müssen in RAP im Gegensatz zu RCP weitere Vorkehrungen getroffen werden. Um solche automatischen UI-Updates in RAP zu ermöglichen, muss der UICallBack-Mechanismus aktiviert werden. Hierzu wird vor dem Start eines neuen Threads, durch den Prozesse im Hintergrund gestartet werden, die Methode UICallBack#activate und am Ende die entsprechende Methode UICallBack#deactivate aufgerufen. Jede Aktivierung benötigt eine eindeutige Session-Identifikation als eine Art Referenz um entscheiden zu können, wann alle Hintergrund-Threads beendet sind.
Die folgenden Schritte verdeutlichen nochmals das Vorgehen:
- CallBack-Mechanismus aktivieren
- Arbeit im Hintergrund beginnen
- UI updaten
- CallBack-Mechanismus deaktivieren
Die Schritte müssen alle innerhalb des UI Threads ausgeführt werden.
Der Quellcode zur Aktivierung des UICallBack-Mechanismus würde folgendermaßen aussehen:
//Schritt 1
//Aktiviere UICallback-Mechanismus
UICallBack.activate("theCallbackId");
Thread myThread = new Thread( bgRunnable );
myThread.start();
Der Quellcode für das UI-Update und die Deaktivierung des UICallBack-Mechanismus wird folgendermaßen ausgeführt:
// Schritt 2
// Hintergrundarbeit beginnen
Runnable theRunnable = new Runnable() {
public void run() {
//eigentliche Abarbeitung...
// Schritt 3
// UI-Update planen
display.asyncExec( new Runnable() {
public void run() {
// Aktualisierung der Oberfläche
}
} );
// Schritt 4
// Deaktiviere den UICallBall-Mechanismus
display.asyncExec( new Runnable() {
public void run() {
UICallBack.deactivate("theCallbackId");
}
} );
}
}
Internationalisierung
Internationalisierung in RAP wird nach dem ähnlichen Prinzip wie in RCP erreicht. In RAP müssen jedoch sowohl verschiedene Sprachen in unterschiedlichen Benutzersessions als auch Änderungen der Sprache innerhalb einer Session unterstützt werden. Aufgrund dieser serverseitigen Multi-user Eigenschaften in RAP können sprachbezogene Informationen im Gegensatz zu RCP nicht statisch in sogenannten Messages-Klassen gespeichert werden. Stattdessen muss für jede Sprache eine eigene Instanz benutzt werden.
In einer Messages-Klasse wird, anstatt des direkten Zugriffs auf ein Resource Bundle (RCP), das RAP NLS-Objekt (Native Language Support) für den Zugriff verwendet. Über die Factory-Methode get() der Zugriffsklasse können Instanzen erzeugt werden, welche Attribute mit den übersetzten Texten beinhalten. Die eigentlichen Übersetzungen der Texte werden jeweils pro Sprache in einer Properties-Datei als Schlüssel-Werte-Paare gepflegt. Die Texte werden über die Zugriffsklasse anhand des jeweiligen Schlüssels ausgelesen und können so in der Benutzeroberfläche angezeigt werden.
RAP selektiert die Sprache für eine Session anhand der gesetzten bevorzugten Sprache und übergibt diese Präferenz im Accept-Language HTTP Header mit jedem Request. RAP versucht daraufhin eine Sprache in der angegebenen Reihenfolge auszuwählen. Falls dies nicht möglich ist, wird die in der Systemvariablen "user.language" gesetzte lokale Sprache herangezogen. Wird keine passende Properties-Datei gefunden, so wird die standardmäßige Properties-Datei (messages.properties) ausgewählt.
Session-Handling und Multi-User Betrieb
Es gibt einen großen Unterschied im Session-Handling zwischen RAP und RCP. Während bei RCP die Anwendung immer nur von einem Benutzer ausgeführt wird, kann eine RAP-Anwendung über den Browser von mehreren Benutzern gleichzeitig verwendet werden. Die Folge ist, dass es bei RAP im Gegensatz zu RCP nicht mehr nur einen Zustand der Anwendung gibt, sondern mehrere parallele Zustände im Webserver vorhanden sind. Abbildung 1 und Abbildung 2 verdeutlichen die Unterschiede nochmals.

Abbildung 1 Client-Server-Architektur bei RCP

Abbildung 2 Client-Server-Architektur bei RAP
Die Zustandsinformationen der Clients werden von RAP in sogenannten Benutzersessions gehalten. Jede Session läuft in einem eigenen Thread ab und hat eine eigene GUI, die im jeweiligen Client-Browser angezeigt wird. Ein Plugin wird somit in einer RAP-Anwendung nur einmal erzeugt, die Workbench hingegen wird für jeden Benutzer neu instantiiert und existiert nur solange wie die Benutzersession.
Diese entscheidenden Unterschiede haben große Auswirkungen auf die Entwicklung einer RAP-Anwendung. So muss bei der Entwicklung genau auf die Entkopplung von Plugin und Workbench geachtet und bei der Implementierung eines Singletons muss die Multi-User-Fähigkeit beachtet werden.
Um das Problem der Singletons im Multi-User-Betrieb zu lösen, kann man in RAP zum einen direkt auf die Session über die Klasse "RWT" zugreifen und zum anderen einen speziellen "RAP-Singleton" programmieren. RAP unterstützt hierbei mit dem Konzept der SessionSingletons, die pro Session eine Instanz zur Verfügung stellen.
Der Code eines SessionSingletons sieht folgendermaßen aus:
public class MySessionSingleton extends
SessionSingletonBase {
public
static MySessionSingleton getInstance() {
return
(MySessionSingleton)getInstance(MySessionSingleton.class);
}
// weiterer Singleton-Code
}
Die Methode getInstance() gibt nun bei jedem Aufruf pro Benutzersession immer dasselbe Objekt zurück.
Durch dieses SessionSingleton-Pattern ist es möglich, benutzerspezifische Daten auch von anderen Servlets ausserhalb des Life Cycles zugänglich zu machen.
Ausblick
In einem weiteren Artikel soll nochmals das Konzept des Single-Sourcings, sowie dessen Umsetzung und die aufgetretenen spezifischen Probleme detaillierten angesprochen werden.
Sascha Seßler ist Softwareentwickler und Certified ScrumMaster bei der Sybit GmbH. Durch seinen Fokus auf Kundennutzen und Effizienz in der Software-Entwicklung bringt er unsere Projekte und die Projekte beim Kunden auf höchstes Qualitätsniveau.
[1] Asynchrones JavaScript and XML: http://de.wikipedia.org/wiki/Ajax_(Programmierung)
[2] http://www.slideshare.net/rsternberg/single-sourcing-rap-and-rcp-desktop-and-web-clients-from-a-single-code-base-1212420
Erschienen in:
Sybit Industry online
Ausgabe:
April 2010
Autor:
Sascha Seßler, Sybit GmbH
Kontakt
Stephanie King
Tel. +49 (0) 7732 9508-106
Fax +49 (0) 7732 9508-111
presse@sybit.de

