4 Realisierung

Aufbauend auf die in Kapitel 3 vorgestellten Anforderungen und die daraus abgeleiteten Konzept-Ideen für die Software-Architektur des Heywow-Systems wird in diesem Kapitel eine Klassenbibliothek für die Entwicklung und Benutzung von Heywow-Diensten vorgestellt.

Durch den Einsatz von 100% purem Java wird der Einsatz im heterogenen System aus verschiedensten Handcomputern als Klienten und leistungsstarken Dienstgebern auf Diensteanbieterseite ermöglicht. Mit dem Aufbau auf die Klassen und Schnittstellen des Jini-Pakets1 können die mit der Bibliothek entworfenen Dienste und Anwendungen in einem beliebigen IP-Netzwerk mit Funk- und Festvernetzung eingesetzt werden.

Da die verfügbaren Versionen der Micro Edition (vgl. Abschnitt 2.1) den Einsatz entfernter Methodenaufrufe (vgl. Abschnitt 2.1.2 RMI) noch nicht unterstützen, ist die Java 2 Standard Edition als Grundlage verwendet worden. Außer dem Einsatz von RMI-Klassen und Schnittstellen ist aber der eingeschränkte Umfang der Micro Edition beachtet worden. In Abschnitt 4.10 werden die wesentlichen Parameter für die übertragung auf die mobile Plattform ausführlicher diskutiert.

Die Klassenbibliothek bietet Klassen und Schnittstellen, die die Implementierung von Heywow-Diensten vereinfachen. Durch den Einsatz des Entwurfsmusters Schablonenmethode wird ein Skelett für den Aufbau von Diensten im Heywow-System vorgegeben. Mit Erweiterung und überschreiben der abstrakten Bibliotheksklassen ist es möglich, beliebige, komplexe Dienstleistungen lokal verfügbar zu machen.

Der Abschnitt 3.2.1 stellt zwei verschiedene Entwicklungsstufen für einen Heywow-Dienst vor. Sowohl die einfache Variante, mit Verwendung der Verwalterklassen aus den net.jini-Paketen, als auch die Möglichkeit des Einsatzes spezieller Jini-Dienste wird näher beschrieben. Mit der Unterstützung des Aktivierungssystems auf den Dienstgebern der Diensteanbieter lassen sich auch Dienste entwickeln, die dort Systemressourcen einsparen können.

Für die Reduktion der Leistungsanforderungen auf dem mobilen Handcomputer unterstützt die Bibliothek neben den Standardprotokollen des Jini-Systems auch ein weiteres Protokoll für den Versand (vgl. Abschnitt 4.5) und Empfang von Dienst-Stellvertreter-Objekten über Multicast.

Für den Einsatz der abstrakten Dienst-Basisklassen werden in Abschnitt 4.3 drei Musterdienste implementiert, die die Funktionalität der gesamten Bibliothek an einfachen Beispielen vorstellen. Im Folgenden werden in Abschnitt 4.7 die Möglichkeiten für die Kommunikation mit dem Heywow-System und den Diensten vom Handcomputer aus in einer einfachen Anwendung implementiert.

Bei der Realisierung der Klassenbibliothek für Heywow wurde Wert gelegt auf eine klare Trennung der Klassen nach ihren Funktionen. Die Aufteilung in Klassenpakete richtet sich nach Verfügbarkeit auf den verschiedenen Hardwarekomponenten.

4.1 Dienste

Das Paket heywow.service bietet Basisklassen für die einfache Konstruktion von Diensten im Heywow-System. Neben den Dienstgebern und Sendebaken von Heywow sind diese Klassen auf den Dienstgebern der Diensteanbieter und den Endgeräten der Benutzer verfügbar.

Ein Dienst besteht aus 3 Komponenten:

  1. Dienstgeberkomponente (ServerObject)
  2. Stellvertreter-Objekt (ServiceInterface)
  3. Starter

Abbildung 4.1: ServiceInterface und ServerObject
ServiceInterface, ServerObject

Jedes der Stellvertreter-Objekte muss die Schnittstelle heywow.service.ServiceInterface unterstützen. Mit dieser Schnittstelle ist es möglich, beim Benutzen eines Jini-Nachschlagedienstes Heywow-Dienste auszuwählen (vgl. Abschnitt 2.2.3). Außerdem wird über die ServiceInterface-Schnittstelle sichergestellt, dass jedes Stellvertreter-Objekt eine Referenz auf die Instanz seines heywow.service.ServerObjects zurückgeben kann. Diese Dienstgeberkomponente muss das unter Jini notwendige Zeitzusicherungsverfahren (vgl. Abschnitt 2.2.4) implementieren und mit getLease() eine gültige Zeitzusicherung für den Dienst zurückgeben können. Die Abbildung 4.1 zeigt in einem UML-Klassenstrukturdiagramm diese beiden grundlegenden Schnittstellen.

Abbildung 4.2: AbstractService
AbstractService

Für den einheitlichen Start eines Heywow-Dienstes wird neben diesen zwei Schnittstellen auch die abstrakte Starterklasse heywow.service.AbstractService (vgl. Abbildung 4.2) angeboten. In ihr wird die Integration in das Betriebssystem auf Dienstgeberseite kontrolliert und der Dienst gestartet.

4.1.1 Abstrakte Dienstgeberkomponente

Zwei abstrakte Klassen, die die beiden Schnittstellen (vgl. Abbildung 4.1) implementieren und allgemeine Funktionalität ergänzen, sind:

Abbildung 4.3: AbstractProxy und AbstractServer
AbstractProxy, AbstractServer

heywow.service.AbstractProxy und heywow.service.AbstractServer (vgl. Abbildung 4.3). Der AbstractServer stellt Methoden zur Sicherung und Wiederherstellung des Dienst-Zustands nach dem ersten Aufruf zur Verfügung. In Jini muss jeder Dienst eindeutig durch einen 128bit Schlüssel identifiziert werden. Diese ServiceID muss auch über Neustarts des Dienstes hinweg, in allen Nachschlagediensten bei der Registrierung gleich bleiben. Die ServiceID, Attribute des Dienstes und erlaubte Gruppen von Nachschlagediensten werden so für jeden Dienst verwaltet.

Beim ersten Start des Dienstes wird die ServiceID nach den Jini-Konventionen (vgl. Jini 1.1 API Dokumentation der Klasse net.jini.core.lookup.ServiceID) mit einem Objekt der Klasse heywow.util.ServiceIDFactory zufällig neu erzeugt. Hierauf hat der Diensteanbieter keinen Einfluss. Anders die Attribute, sie müssen von einem konkreten Dienstgeber durch die Implementierung von createAttributes() festgelegt werden. Die Gruppennamen interessanter Jini-Nachschlagedienste werden ebenfalls in der Implementierung festgelegt.

Bei späteren Neustarts stellt AbstractServer diesen Zustand wieder vollständig her.

Die abstrakte Dienstgeberkomponente implementiert die Methode start() aus der ServerObject-Schnittstelle und führt abhängig von Art und Zeitpunkt des Aufrufs die (Wieder-)Registrierung des konkreten Stellvertreter-Objekts in allen interessanten Nachschlagediensten durch. Hierzu muss die konkrete Dienstgeberkomponente die beiden Methoden createAttributes() und createProxy(), mit der Instanziierung des Stellvertreters, implementieren.

Für die dauerhafte Registrierung in den Nachschlagediensten des Heywow-Systems werden die unterstützenden Klassen des Jini Starter Kits in net.jini.discovery, net.jini.lease und net.jini.lookup verwendet. Mit den verschiedenen Verwalterklassen werden die Standardaufgaben im Jini-System geregelt.

4.1.2 Abstraktes Stellvertreter-Objekt und Zeitzusicherungen

Die Elternklasse aller Stellvertreter-Objekte im Heywow-System, heywow.service. AbstractProxy, unterstützt die Schnittstelle ServiceInterface. Für den Vergleich von Stellvertreter-Objekten aus verschiedenen Nachschlagediensten bietet AbstractProxy die Methode equals(), die die Gleichheit anhand der gespeicherten ServiceID feststellt. Das Stellvertreter-Objekt eines Dienstes wird in allen interessanten, lokalen Nachschlagediensten registriert. Beim Lookup-Prozess (vgl. Abschnitt 2.2.3) auf einem Klienten werden somit über Jini auch mehrere Objekte aus verschiedenen Nachschlagediensten bezogen. Dubletten müssen deshalb beim Aufbau des WID-internen Zwischenspeichers eliminiert werden. Außerdem wird in AbstractProxy eine Referenz auf die zugehörige ServerObject-Instanz gespeichert.

Ein Klient kann über das bezogene Stellvertreter-Objekt von der zugehörigen Dienstgeberkomponente eine Zeitzusicherung anfordern.

Abbildung 4.4: AbstractServer und LandlordServer
AbstractServer, LandlordServer

Dieser AbstractServer tritt wiederum als Vermittler auf und leitet die Anfrage an eine Instanz von heywow.service.support.LandlordServer weiter (vgl. Abbildung 4.4).

Die Klasse LandlordServer implementiert das Protokoll eines Landlords (vgl. Abschnitt 2.2.4) und verwaltet für den Dienst vergebene Zusicherungen. Die Dienstgeberkomponente des Dienstes kann auch ohne einen LandlordServer erzeugt werden, wenn auf die Vergabe von Zeitzusicherungen verzichtet wird.

4.1.3 Abstrakter Starter

Für den Start eines Dienstes bietet das Rahmensystem eine abstrakte Starterklasse (vgl. UML-Klassenstrukturdiagramm in Abbildung 4.2) an. Durch Vererbung von der Basisklasse heywow.service.AbstractService kann ein Dienst eine Starterklasse mit einer main()-Methode implementieren. Die abstrakte Elternklasse enthält in ihrem Konstruktor das Skelett für den Start eines Dienstes. Eine konkrete Klasse muss die Methode createServer() implementieren und dort die Dienstgeberkomponente des Dienstes instanziieren. AbstractService startet diese nach der Erzeugung.

4.1.4 Abstrakte, aktivierbare Dienstgeberkomponente

Im Gegensatz zur einfachen Instanziierung

serverObj = (ServerObject) new ConcreteServer();
kann bei der aktivierbaren Variante eines Dienstes die Dienstgeberkomponente im Java-Aktivierungssystem registriert und dort eine aktiviertes Objekt erzeugt werden.

Mit dieser Form des Dienststarts können auf den Dienstgebern der Diensteanbieter Systemprozesse, die nur im Leerlauf sind, eingespart werden und auch dort die nötigen Systemressourcen reduziert werden.

Die Starter-Variante des aktivierbaren Dienstes bietet eine zusätzliche Methode activate(), die den vollständigen Name der Dienstgeber-Klasse und die nötigen Parameter, verpackt als MarshalledObject, als Parameter entgegennimmt.

AbstractActivatableService erbt selbst von AbstractService und ergänzt den Konstruktor der Elternklasse nur um das Beenden des Starterprogramms nach der erfolgreichen Registrierung der Dienstgeberkomponente im Aktivierungssystem.

Abbildung 4.5: Zusammenspiel der konkreten Klassen eines aktivierbaren Dienstes mit dem Aktivierungssystem von Java (vgl. Abschnitt 2.1.3)

Das Sequenzdiagramm in Abbildung 4.5 veranschaulicht das dynamische Zusammenspiel der einzelnen Klassen und Komponenten im Heywow-System:

Nach dem Aufruf des Starters eines konkreten, aktivierbaren Dienstes muss durch die Methode createServer() die Dienstgeberkomponente instanziiert werden. Beim aktivierbaren Dienst wird dies mit der Registrierung im Aktivierungssystem verbunden. Hierzu bietet AbstractActivatableService2 die Methode activate() an.
Nach der Registrierung wird ausgehend von der zurückgegebenen eindeutigen ActivationID die Dienstgeberkomponente aktiviert und eine Referenz zurückgegeben. Mit diesem Objekt wird der Dienst, wie ein nichtaktivierbarer, gestartet.

Da die Dienstgeberkomponente nicht dauerhaft rechnen muss, und sich bei Leerlauf selber beendet, kann sie nicht für die dauerhafte Registrierung im Jini-System verwendet werden. AbstractActivatableServer besitzt keine Verwalterklassen aus dem Jini Starter Kit.

Für aktivierbare Dienste bietet Sun Microsystems Jini-Dienste, die in Nachschlagediensten registriert werden, an. Teil des Jini Starter Kits ist ein Nachschlagedienst-Entdeckerdienst (LookupDiscoveryService) namens fiddler, der eingesetzt werden kann, um interessante Nachschlagedienste zu finden. Wenn dieser Unterstützerdienst einen neuen Nachschlagedienst entdeckt, aktiviert er die Dienstgeberkomponente des Dienstes und diese registriert das Dienst-Stellvertreter-Objekt dort.

Auch die Verwaltung der dort erhaltenen Zeitzusicherung wird über einen Jini-Dienst (norm) geregelt. Mit diesem Nutzungszeitverlängerungsdienst (LeaseRenewalService) aus dem Jini Starter Kit kann die Dienstgeberkomponente die regelmäßige Erneuerung von erhaltenen Zeitzusicherung an diesen Dienst delegieren.

Der AbstractActivatableService, bzw. der konkrete Starter kann nach erfolgreicher Registrierung der Dienstgeberkomponente im Aktiverungssystem beendet werden. Für diese Einsparung von Systemressourcen sind aber laufende Prozesse für den RMI-Activation-Daemon (rmid), den Nachschlagedienst und die Entdecker- und Verlängerungsdienste notwendig.

Wird der heywow.service.AbstractActivatableServer über das Aktivierungssystem instanziiert, wird sofort ein Stellvertreter-Objekt mit der Information von ServiceID und ActivationID erzeugt. Jede konkrete Dienstgeberkomponente muss hierfür wieder eine Methode createProxy() implementieren, die dieses Muster erzeugt. Außerdem wird im Konstruktor auch die Methode createAttributes() aufgerufen.

Neu ist eine Methode notify(), aus der RemoteEventListener-Schnittstelle, die mit einem net.jini.core.event.RemoteEvent durch die unterstützenden Dienste aufgerufen wird. Das Aktivierungssystem ist dafür zuständig, dass bei Bedarf die aktivierbare Dienstgeberkomponente in einer neuen JVM instanziiert wird. Nach einer Benachrichtigung kann über das RemoteEvent entschieden werden, welche Aktivität vom Dienstgeber-Objekt erforderlich ist.

Abbildung 4.6: AbstractActivatableProxy, AbstractActivatableServer
AbstractActivatableProxy, AbstractActivatableServer

Die Abbildung 4.6 zeigt das UML-Klassendiagramm von AbstractActivatableProxy und AbstractActivatableServer, mit den wesentlichen Methoden und Variablen.

Auch für die Verwaltung der Zeitzusicherungen, die der Dienst an seine Klienten vergibt, ist die Dienstgeberkomponente zuständig. Falls über die getServerObject()-Methode im Stellvertreter eine Instanz der Dienstgeberkomponente referenziert wird, aktiviert die Klasse AbstractActivatableProxy evtl. die nicht aktive Komponente über die gespeicherte ActivationID.

Und wenn nach dieser Aktivierung eine Zeitzusicherung für den Dienst angefordert wird, muss der Prozess auf dem Dienstgeber aktiv bleiben um mit seinem LandlordServer-Objekt die vergebenen Zeitzusicherungen zu verwalten.

Der AbstractActivatableServer implementiert eine neue Methode start(), die an das neue Verfahren mit den Unterstützer-Jini-Diensten angepasst ist. Mit dem Einsatz der Jini-Dienste werden die abstrakten Methoden (re-)register() aus AbstractServer nicht weiter unterstützt.

4.1.5 Versionsattribut

Eine konkrete Klasse im Paket heywow.service ist die Implementierung für ein Jini-Dienste-Attribut. Mit heywow.service.Version kann die Programmversion eines angebotenen Dienstes näher beschrieben werden. Dieses Dienste-Attribut ist für den Vergleich, z.B. mit dem eines zwischengespeicherten Stellvertreters, nötig.

2. Unterstützerklassen

Die Klasse LandlordServer (vgl. Klassendiagramm in Abbildung 4.4) aus dem Paket heywow.service.support implementiert die Schnittstelle für einen Landlord (vgl. Abschnitt 2.2.4). über entsprechende Objekte können Zeitzusicherungen nach diesem Verfahren verwaltet werden.

Die Klasse, die von einer Dienstgeberkomponente instanziiert werden kann, speichert erzeugte Zusicherungen in einer Datenbasis. Regelmäßig wird diese nach veralteten Einträgen durchsucht und gereinigt. Bei der Konstruktion eines LandlordServer-Objekts kann die gewünschte Zusicherungsdauer übergeben werden. Zeitzusicherungen, die mit der Methode getLease(), aus ServerObject, angeforderten werden, trägt der Verwalter dann mit einer Referenz auf den Klienten, als Schlüssel, in seine Datenbasis ein.

Dies ist bei der Verwendung eines speziellen Verwalters für jede Dienstgeberkomponente ein ausreichender, eindeutiger Schlüssel. Erst wenn ein LandlordServer-Objekt für mehrere Dienste die Zeitzusicherungen verwaltet, muss der Schlüssel anders berechnet werden.

Für die Rückgabe gültiger Zeitzusicherungen wird die Implementierung einer LandlordLeaseFactory verwendet [Edw1999, Kap. 11]. Der LandlordServer wird für die erzeugten Zeitzusicherungen als Landlord registriert und implementiert die nötigen Methoden für die Verwaltung.

Eine weitere von den Dienst-Basisklassen benötigte Klasse in diesem Heywow-Paket ist FindAService. Mit Objekten dieser Klasse kann in den Nachschlagediensten des Heywow-Systems ein Stellvertreter-Objekt mit einer vorgegebenen Schnittstelle gesucht werden. Aufbauend auf die Kern-Klassen von Jini wird ein einfacher DiscoveryListener implementiert. Mit der Methode getService() kann synchronisiert das erste gefundene Objekt dieser Schnittstelle, z.B. für die Suche nach Nachschlagedienst-Entdeckerdiensten und Nutzungszeitverlängerungsdiensten bei aktivierbaren Heywow-Diensten, bezogen werden.

3. Beispieldienste

Im heywow.example-Paket sind drei einfache Heywow-Dienste implementiert, die die Verwendung der abstrakten Basisklassen und Schnittstellen aus Abschnitt 4.1 im Paket heywow.service erklären.

4.3.1 'Hej Marc'-Dienst

Abbildung 4.7: Klassen des 'Hej Marc'-Dienstes
'Hej Marc'-Dienst

Der 'Hej Marc'-Dienst (vgl. Abbildung 4.7) implementiert mit seinem Stellvertreter-Objekt die Schnittstelle HejMarcServiceInterface, die eine Methode sayHej() mit einer Begrüßungszeichenkette als Rückgabewert definiert.

Der Starter HejMarcService erbt von AbstractService und ergänzt die abstrakte Klasse um eine einfache main()-Methode. Hier wird der korrekte Aufruf des Starters kontrolliert und der Starter instanziiert.

Der Dienstgeber besitzt keinen LandlordServer zur Erzeugung und Verwaltung von Zeitzusicherungen. Die Methode getLease() wird überschrieben, gibt nur die null-Referenz zurück und zeigt damit an, dass das Stellvertreter-Objekt immer gültig bleibt. Ein solches Stellvertreter-Objekt wird, nachdem es in den WID-internen Zwischenspeicher kopiert worden ist, dort bis auf weiteres für Anwendungen auf dem Handcomputer bereitgehalten. Eine Funk-Verbindung vom Stellvertreter-Objekt zur Dienstgeberkomponente ist nicht nötig.

Da die Zeitzusicherungen für den dauerhaften Eintrag in einen Nachschlagedienst aber regelmäßig erneuert werden müssen, kann das Dienstgeber-Programm nicht beendet werden. Der Dienstgeber erzeugt einen zusätzlichen Kontrollfaden (vgl. Abschnitt 2.1.1), der ohne Unterbrechung weiterläuft und kann so mit den Unterstützerklassen aus dem Jini Starter Kit seine Registrierungen erneuern und sich in neuen Nachschlagediensten eintragen.

4.3.2 'Totally Different'-Dienst

Abbildung 4.8:Klassen des 'Totally Different'-Dienstes
'Totally Different'-Dienst

Der zweite Muster-Dienst, mit dem Starter heywow.example.TotallyDifferent Service (vgl. Abbildung 4.8), bietet den gleichen Funktionsumfang, implementiert aber eine unabhängige Schnittstelle.

heywow.example.TotallyDifferentInterface definiert zwar ebenfalls eine Methode sayHej(), steht aber in keinerlei Beziehung zum ersten Dienst.

Zum Starter des 'Hej Marc'-Dienstes besteht ebenfalls kein großer Unterschied. Erst die Dienstgeberkomponente des Dienstes zeigt neue Möglichkeiten der Klassenbibliothek. In TotallyDifferentServer wird durch einen anderen Konstruktor der Elternklasse (AbstractServer) ein LandlordServer-Objekt zur Verwaltung von Zeitzusicherungen instanziiert. Die Methode getLease() wird jetzt an die Methode des Verwalters weitergereicht.

Außerdem wird bei der Registrierung des Stellvertreter-Objekts zusätzlich auch eine Menge von Attributen mit im Nachschlagedienst gespeichert (vgl. Abschnitt 2.2.5). Die Beispielklasse heywow.example.Simple erweitert die Klasse AbstractEntry aus dem Jini-Paket und kapselt einen Integer-Wert. Mit die Klasse SimpleBean kann dieser auch vom Dienst oder einem Klienten geändert werden.

3. Aktivierbarer Dienst

Abbildung 4.9:Klassen eines aktivierbaren Dienstes (TheOneAndOnly*)
Aktivierbarer Dienst

Die Verwendung der Basisklassen für einen aktivierbaren Dienstgeber wird mit der Starterklasse heywow.example.TheOneAndOnlyService (vgl. Abbildung 4.9) verdeutlicht.  
TheOneAndOnlyServer ist ein ServerObject und erbringt neben der Funktionalität für die Verwaltung der Zeitzusicherungen an Klienten auch den eigentlichen Dienst.

Das Stellvertreter-Objekt (heywow.example.TheOneAndOnlyProxy) leistet jetzt nur die Kommunikation zum Dienstgeber. Die Funktionalität gleicht wieder der bisherigen Aufgabe, es wird eine einfachen Begrüßungszeichenkette zurückzugeben. Der TheOneAndOnlyProxy verwendet dazu aber das TheOneAndOnlyServer-Objekt auf einem Dienstgeber. Der Zugriff erfolgt über einen entfernten Methodenaufruf mit Verwendung der Schnittstelle heywow.example.UseProtocol.

Die Methode use() reagiert auf den Aufruf mit einer Zeichenkette, die im Umlauf aus einer kleinen Datenbasis ausgewählt wird.

Neben der Verwendung der Dienstgeberkomponente für die Erbringung des Dienstes, zeigt die Dienstgeberkomponente TheOneAndOnly auch die Java-Möglichkeiten des Aktivierungssystems.

Der Starter, heywow.example.TheOneAndOnlyService, erbt wie die anderen Komponenten des Dienstes, von den *Activatable*-Klassen. Nach der Aktivierung durch den Starter kann sich die Dienstgeberkomponente, wenn sie sich im Leerlauf befindet, beenden.

Das einfache Beispiel unterstützt keinerlei Sicherheitsprotokoll. Beliebig viele Klienten können sich gegenseitig beeinflussen und die Rückgabe für die anderen verändern.

4.4 WID-interner Zwischenspeicher

Auf Seiten des Handcomputers unterstützt die Klassenbibliothek den Entwurf von Anwendungen für den Benutzer.

Der Benutzer will auf die lokal verfügbaren Dienstleistungen, die seinen Interessen entsprechen, zugreifen. Dafür müssen aus den Nachschlagediensten des Heywow-Systems die entsprechenden Stellvertreter-Objekte bezogen werden. Für die Verwendung der Dienste auf einem mobilen Endgerät wird ein WID-interner, erkundender Nachschlagedienst als Zwischenspeicher eingesetzt (vgl. Abschnitt 3.2.2). Durch Einsatz eines DiscoveringLUS-Objekts kann die Anwendung auf dem Handcomputer alle im lokalen Netzwerk erreichbaren Nachschlagedienste erforschen und dort interessante und vom Benutzer gefragte Dienst-Stellvertreter-Objekte nachschlagen lassen.

Mit dieser Bezugsform baut der DiscoveringLUS im Paket heywow.util auf die Kommunikationsprotokolle von Jini auf und erzeugt einen WID-internen Zwischenspeicher. Dieser funktioniert eingeschränkt unabhängig von der Funkverbindung3 des Handcomputers zu den Sendebaken des Heywow-Systems.

Durch die Methode getService(ServiceTemplate) wird der Zwischenspeicher für das übergebene Stellvertreter-Muster erzeugt und die Suche gestartet. Ein ServiceTemplate ermöglicht die Einschränkung der Suche nach interessanten Stellvertreter-Objekten auf die Implementierung bestimmter Schnittstellen, eine Menge von Attributen oder eine bestimmte ServiceID. Bei erfolgreicher Suche im lokalen Netz benachrichtigt der WID-interne, erkundende Nachschlagedienst die Anwendung, und die übergebene Referenz auf die Datenbasis kann verwendet werden, um die entsprechenden Stellvertreter-Objekte einzusetzen.

Beim Konzept des entfernten Methodenaufrufs (vgl. Abschnitt 2.1.2 RMI) wird die Objekt-Serialisierung für die übertragung beliebiger Java-Objekte verwendet. Die serialisierbaren Objekte, insbesondere die Stellvertreter-Objekte, unterstützen die java.io. Serializable-Schnittstelle, eine Schnittstelle ohne Methodenbeschreibung oder Konstanten. Sie ist im Java-System nur als Marke notwendig. Die Versendung der in Nachschlagediensten registrierten Stellvertreter-Objekte erfordert dies und benötigt zusätzlich den Bezug der Bytecode-Datei für die Objekt-Schnittstelle. Für diesen Zweck müssen die übersetzten Programmdateien von einem Web-Dienstgeber mit HTTP bezogen werden können.

Da Java aber auch die Möglichkeit bietet beliebige Java-Objekte ohne Kenntnis ihrer Schnittstelle zu benutzen (vgl. Abschnitt 2.1.5 Reflection), können die Anwendungen auf dem Endgerät die Objekte auch ohne Bezug der Bytecode-Dateien inspizieren und benutzen.

Für den stromsparenden Betrieb des Handcomputers kann der energieverbrauchende, sendende Zugriff über Jini noch weiter eingeschränkt werden. Mit einem speziellen Protokoll über Multicast können alle Proxy-Objekte, die an eine Multicast-Gruppe gesendet werden, durch energiesparenderes Belauschen der Adresse mit heywow.wid. ProxySniffer bezogen werden.

Der ProxySniffer erweitert den allgemeinen heywow.wid.MulticastSniffer, der ein Empfangsprotokoll für beliebige Objekte unterstützt.

Mit MulticastSniffer wird eine IP-Adresse belauscht und für jedes erhaltene Datenpaket eine Datenstruktur aufgebaut. Die zusammengehörenden Datagramm-Pakete werden wieder in der richtigen Reihenfolge zusammengesetzt. Erst wenn ein Objekt vollständig erlauscht ist, wird von der konkreten Kindklasse ProxySniffer die Methode handleData() aufgerufen, um das erhaltene Objekt zu deserialisieren und in eine WID-interne Datenbasis aufzunehmen.

Analog zur Einschränkung der Suche nach interessanten Stellvertreter-Objekten bei DiscoveringLUS kann auch mit dem ProxySniffer der Suchraum durch übergabe eines ServiceTemplate-Objekts eingeschränkt werden. Objekte, die mit den Methoden aus MulticastSniffer empfangen werden, werden dynamisch geprüft und nur bei Unterstützung der gewünschten Schnittstellen oder Attribute in den Zwischenspeicher aufgenommen.

4.5 Sendebake

Neben dem Empfänger-Handgerät muss auch ein Sender auf den Sendebaken das Multicast-Protokoll unterstützen. Die Klasse heywow.beacon.MulticastAdvertiser implementiert das Protokoll abstrakt. Die über UDP versendeten Datagramm-Pakete enthalten neben dem Java-Objekt auch einen Protokoll-Kopf mit zusätzlichen Informationen. UDP-Datagramm-Pakete sind selbst wieder Java-Objekte, die über entsprechende Kommunikationsstellen (MulticastSockets) von Java-Anwendungen gesendet und empfangen werden können. Die maximale Größe der gesendeten Daten in den Datagramm-Paketen ist auf 1024 Byte festgelegt. Von diesem Kilobyte Daten werden 20 Bytes für das Protokoll verwendet.

0-15:
Schlüssel (ServiceID)
16:
Paketgesamtanzahl (Byte)
17:
Paketnummer (Byte)
18,19:
Version (Integer)
20-:
Daten
Jedes Paket identifiziert seinen Dateninhalt über einen eindeutigen 128bit-Schlüssel. über ein Byte für die Gesamtanzahl der Pakete zu jedem Schlüssel und einem Index für das aktuelle Datagramm-Paket kann die Reihenfolge auch auf der Seite des Empfängers wieder richtig zusammengesetzt werden.

Wenn für den Stellvertreter ein Versionsattribut in die Nachschlagedienste eingetragen ist, wird dies unter Index 18 und 19 ebenfalls in die Multicast-Datagramme verpackt und somit eine einfache Auswahl aktueller Versionen auf dem Handgerät ermöglicht.

Von Index 20 bis zum Ende des Datensatzes ist es dann möglich, ganze Objekte oder indizierte Objektstücke über Multicast zu versenden.

MulticastAdvertiser bietet allen erbenden Klassen dazu zwei Methoden an:

protected void advertiseBytes(byte[] data, 

                 ServiceID serviceID, 

                 byte[] versionBytes, int port)

protected void advertiseObj(Object obj, 

                 ServiceID serviceID, 

                 Version version, int port)

Die Methode advertiseObj() nimmt ein beliebiges Java-Objekt, wandelt es in einen Byte-Strom und versendet diesen mit advertiseBytes().

Mit einem Objekt der konkreten Klasse heywow.beacon.ProxyAdvertiser kann der lokale Nachschlagedienst auf der Sendebake mit einem DiscoveringLUS beobachtet und der erhaltetene Inhalt über Multicast mit advertiseObj() aus MulticastAdvertiser versendet werden.

Neben dem Versand vollständiger Stellvertreter-Objekte, die in bis zu 256 Datagramm-Paketen verpackt werden können, kann für ein Stellvertreter-Objekt auch lediglich die ServiceID des Dienstes und die Adresse des Nachschlagedienstes versendet werden. Die Entscheidung, ob der Dienst für den Benutzer notwendig ist, kann dann die Anwendung auf dem Handcomputer anhand der Dienst-Attribute und der mitgesendeten Methoden-Schnittstelle entscheiden. Für diese Verwendung wird kein Stellvertreter-Objekt direkt verschickt, sondern ein Ersatzobjekt (vgl. Abbildung 4.10), das Informationen über das tatsächliche Objekt enthält.

Abbildung 4.10: ProxySurrogate
ProxySurrogate

In heywow.service.ProxySurrogate wird entweder ein Stellvertreter-Objekt gekapselt oder die URL des Nachschlagedienstes, in dem das Objekt über Jini bezogen werden kann, gespeichert. Um der Anwendung auf dem Handcomputer die Entscheidung, ob das Stellvertreter-Objekt nachgeschlagen wird, zu ermöglichen werden die mit dem Dienst gespeicherten Attribute, sowie eine Liste der verfügbaren Methoden mitgesendet.

In Java ist es möglich, mit einem MulticastSocket die Multicast-Kommunikation zu implementieren. Der MulicastSocket erlaubt das Betreten einer Multicast-Gruppe und das Belauschen des dortigen Datenverkehrs.

Multicast-Adressen oder Multicast-Gruppen sind normale IP-Adressen. Sie beginnen mit der Bytefolge 1110 und werden als Class D Adressen bezeichnet. Der Multicast-Adressbereich ersteckt sich von 224.0.0.0 bis 239.255.255.255 [Har1997, Kap. 13]. Eine Multicast-Adresse beschreibt Rechnern im Netz, die an dieser Gruppe teilnehmen. Das IANA (Internet asssigned Number Authority) ist verantwortlich für die Vergabe von permanenten Multicast-Adressen4. Dort ist im Moment auch die Registrierung der IP-Adressen für das Multicast-Verhalten des Discovery-Protokolls in Jini (vgl. Abschnitt 2.2.2) beantragt. Mit der Adresse ALL-SYSTEMS.MCAST.NET (224.0.0.1) können alle Systeme auf dem lokalen Subnetz erreicht werden. Für weitergehende Netzstrukturen kann den einzelnen Datenpaketen (UDP-Datagramm-Paketen) im Netzwerk auch ein Time-To-Live (TTL) Zähler mitgegeben werden. Dieser Zähler wird bei jedem passierten Router um mindestens 1 verringert und wenn der Wert 0 erreicht hat wird das Datenpaket nicht weitergesendet.

Ein Nachteil des Multicast-Versands ist zwar, dass die Netzlast in denjenigen Segmenten unnötig hoch werden kann, für welche die Daten nicht bestimmt sind, aber insbesondere in Heywow kann dies umgangen werden, weil die Datenpakete eines lokalen Senders nur in seinem lokalen Subnetz verschickt und empfangen werden müssen.

Neben einem Sender (ProxyAdvertiser) für den Versand der auf der Bake verfügbaren Stellvertreter-Objekten bietet jede Sendebake auch die nötigen Dienste für ein Jini-Netzwerk.

Für die erste Entwicklungsstufe ist der Standard-Nachschlagedienst aus dem Jini-Paket, reggie, ausreichend. Auch an den Web-Dienstgeber werden keine außergewöhnlichen Voraussetzung gestellt. Den Zugriff auf Java-Klassen über HTTP bietet auch schon das einfache Tool aus der Standard-Implementierung für Jini von Sun. Wenn evtl. das Angebot anderer Quellen auf diesem Weg nötig ist, kann auch ein vollwertiger Dienstgeber für alle Dateien im lokalen Dateisystem verwendet werden.

4.6 Nutzklassen und Ereignisse

Im Paket heywow.util sind einige nützliche Klassen und Schnittstellen des Heywow-Systems gesammelt. Mit Constants werden die notwendigen Konstanten definiert und damit die einfache Anpassung an andere Systemparameter ermöglicht.

Für die Verwendung von ServiceID-Objekten bietet die Klasse ServiceIDFactory Methoden zur Erzeugung und deren Umwandlung aus und in einfache Bytefolgen an.

Durch den Einsatz der zwei verschiedenen Bezugsformen für die Dienst-Stellvertreter-Objekte ist eine einheitliche Schnittstelle zusammen mit Ereignissen (Events) und Beobachtern (Listenern) für die synchronisierte Verarbeitung der Ereignisse notwendig.

Sowohl heywow.util.DiscoveringLUS als auch heywow.wid.ProxySniffer5 erben deshalb von heywow.util.AbstractExplorer. In dieser abstrakten Klasse werden die Gemeinsamkeiten der beiden Protokollformen, beim Aufbau einer WID-internen Datenbasis von Stellvertreter-Objekten, zusammengefasst. Außerdem werden hier für beide Klassen Beobachter (heywow.event.ExploredListener) registriert und verwaltet. Objekte, die die Schnittstelle ExploredListener implementieren, werden bei erfolgreicher Suche nach Stellvertreter-Objekten mit einem Ereignis (heywow.event.ExploredEvent) benachrichtigt und können dann auf den erstellten Zwischenspeicher zugreifen.

Durch diese zusätzliche Vererbungshierarchie wird der Gebrauch der verschiedenen Protokolle vereinheitlicht. Auf diese Weise können beide Protokolle für den Benutzer transparent eingesetzt und ausgetauscht werden.

4.7 WID-Anwendungen

Neben den drei Beispieldiensten (vgl. Abschnitt 4.3) enthält die Java-Bibliothek in heywow.client auch noch verschiedene Muster für Anwendungen auf dem Handcomputer.

Mit der Java-Anwendung heywow.client.LUSContent kann der Inhalt aller im lokalen Netz erreichbaren Nachschlagedienste angezeigt werden. Die Applikation baut auf den Kernklassen des Jini-Programmiersystems auf. Es werden allgemeine Informationen über die gefundenen Nachschlagedienste, eine Liste aller mit einem Dienst registrierten Attribute, sowie die Klassen der gespeicherten Stellvertreter aufgelistet.

Diese Anwendung eignet sich für den Test der Funktionstüchtigkeit der entwickelten Dienste. Es werden keine weiteren Klassen aus der Heywow-Bibliothek und nur Basisklassen des Jini-Systems verwendet.

Ein Muster für eine Anwendung, wie sie auch auf einem Endgerät denkbar wäre, ist heywow.client.UI.

Abbildung 4.11: WID-Musteranwendung
WID-Musteranwendung

Die Anwendung (vgl. Abbildung 4.11) setzt beide Bezugsmethoden für Stellvertreter-Objekte, die das Heywow-System anbietet, ein.

Die Klasse implementiert einen heywow.event.ExploredListener und kann sowohl mit DiscoveringLUS als auch mit ProxySniffer eine WID-interne Datenbasis der lokal verfügbaren Stellvertreter aufbauen.

Die Anwendung selbst ist unter Verwendung der Grafikklassen von kAWT6 entwickelt. Diese Klassenbibliothek bietet für die Java 2 Micro Edition eine fast vollständige Implementierung der Basisklassen der java.awt-Pakete.

4.8 Konfiguration

Bei der Entwicklung der Klassenbibliothek für das Heywow-System wurde Wert auf eine funktionale Trennung der einzelnen Klassen gelegt.

Somit ist es möglich, durch Erzeugung von Java-Dateiarchiven die nötigen Klassen für die einzelnen Softwarekomponten zu trennen.

Bei der Verwendung beliebiger Heywow-Dienste auf einem mobilen Endgerät, ist es möglich, die Kommunikation, z.B. für den Bezug von Klassen-Dateien über HTTP-Dienstgeber, auf den Handcomputer zu verringern. Die Basisklassen auf denen alle Dienste aufbauen, können schon fest installiert sein und nur konkrete Dienste-Klassen müssen über Jini oder Multicast dynamisch bezogen werden.

4.9 Test

Zum Test der Klassenbibliothek mit den implementierenden Beispieldiensten wurde die Java 2 Standard Edition (vgl. Abschnitt 2.1), die eine Unterstützung von RMI bietet, eingesetzt. Als Hardwarebasis wurde ein Festnetz aus Arbeitsplatzrechnern verwendet, und dort der Einsatz der Dienste getestet.

Der Ansatz von 100% purem Java, mit der Verwendung von Jini als Basistechnologie, ermöglicht aber auch eine einfache, kostensparende Entwicklung der Heywow-Dienste in bestehenden lokalen Netzwerken. Mit der Portierung der aktuellen Version der Connected Limited Device Configuration CLDC 1.0 nach Linux besteht eine professionelle Entwicklungsumgebung [Hei2000].

Außerdem ermöglicht eine Beschränkung im Funktionsumfang der Standard Edition schon jetzt die Implementierung und den Test von Diensten.

4.10 übertragung

Eine große Hürde bei der übertragung der Dienste und Anwendungen im Heywow-System auf die mobile Plattform ist im Moment noch das Fehlen einer vollständigen RMI-Unterstützung für eine Implementierung der Mirco-Edition.

Mit dem J2ME RMI-Profil [JSR2000b] gibt es zur Zeit nur eine Spezifikation im Entwicklungsstadium, die auf die Java 2 Micro Edition CDC (vgl. Abschnitt 2.1) aufbaut. Mit einer Implementierung nach dieser Spezifikation soll der entfernte Methodenaufruf analog zur Standard Edition auch auf kleineren Geräten ermöglicht werden.

Ohne diese Erweiterung ist derzeit noch kein Kommunikationstandard auf RMI-Basis unter Java für tragbare Kleinstcomputer verfügbar. Alle Implementierungen basieren bisher auf anderen Schnittstellen. Deren Verwendung wurde beim Entwurf der Java-Klassenbibliothek, zugunsten eines reinen Java-Standards verworfen.

Durch den Aufbau der gesamten Klassenbibliothek auf die Basis eines IP-Netzwerks ist es neben der einfachen Integration in bestehende lokale Festnetze auch möglich, zukünftige Entwicklungen bei den lokalen Funknetzen zu nutzen.

4.11 Zusammenfassung und Bewertung

Ziel der Arbeit war es, eine Software-Architektur für die lokale Dienstleistungserbringung im Heywow-System zu schaffen, die es ermöglicht, von einem mobilen Handcomputer aus, lokal in einem IP-Funknetzwerk auf beliebige Dienste zuzugreifen.

Nach einer Einführung verschiedener Grundlagen in Kapitel 2 wurden in Kapitel 3 schrittweise die wesentlichen Anforderungen an das System erarbeitet und daraus Entscheidungen für die Architektur abgeleitet.

Schließlich wurde in 100% purem Java eine Klassenbibliothek implementiert (vgl. Kapitel 4), die das Skelett für lokale Dienste bietet und leicht mit Dienst-Funktionalität zu konkreten Diensten erweiteret werden kann.

Durch die Einführung eines Java-Rahmensystems für lokale Dienste, aufbauend auf Jini, basierend auf einer TCP/IP-Netzwerk-Architektur, ist es auch möglich das Angebot zentraler Dienstleistungen tranparent in das System zu integrieren. Dem Benutzer eines mobilen Handcomputers kann durch den Zugriff auf private Daten, Termine und Informationen eine personalisierte Leistung angeboten werden, die dezentral von lokalen Diensteanbietern entwickelt werden kann.

Das Skelett für Dienste im Heywow-System ermöglicht dem Benutzer den Zugriff auf völlig neue und unbekannte Dienstleistungen. Die Dienste können sowohl einfache Daten, wie z.B. Ortinformationen für zielgenaue lokale Navigation ermöglichen,


1) Verwendet wurde die Implementierung von Sun Microsystems in der Version 1.1 beta2
2) Eine spezialisierte abstrakte Klasse, die von heywow.service.AbstractService erbt.
3) Nur beim Bezug der Stellvertreter-Objekte und bei der evtl. Verhandlung über Zeitzusicherungen ist eine unterbrechungsfreie Funkverbindung notwendig.
4) aktuelle Liste: ftp://ftp.isi.edu/in-notes/iana/assignments/multicast-addresses
5) ProxySniffer erbt über MulticastSniffer und implementiert die notwendigen Methoden.
6) Informationen und Quellen unter: http://www.kawt.de.

----------------------------------------------------------------
[home] [TOC] [prev] [next] [guestbook] [contact]          (c) SM