Realisierung verteilter Anwendungen: Teil 4 zBeim vorigen Mal: RMI und Grundlagen von CORBA zInhalt heute yVerteilung und Objektorientierung (Voyager) ySpontane Vernetzung (Jini) zLernziele: yVerständnis der Probleme und Lösungsansätze bei Objektmigration und spontaner Vernetzung Ralf Möller, FH-Wedel
Voyager zZu Java kompatible Laufzeitumgebung und Bibliothek, die auf eine umfassende Lösung für sehr viele Bereiche und Probleme der Programmierung verteilter Systeme zielt zFunktions- und Leistungsumfang wächst mit jeder neuen Version zIn dieser Vorlesung nur grundlegende Techniken
Basistechniken (1) zEntfernte Objekte yErzeugung eines entfernten Objekts aus einem lokalen Objekt zur Laufzeit und zu jeder Java-Klasse zEntfernte Referenzierung yTransparente Referenzierung entfernter Objekte yTyp: gemeinsames Interface zEntfernte Erzeugung yErzeugung von Objekten in einer anderen VM (statt nur Erzeugung lokaler Objekte) yAutomatische Erzeugung von lokalen Stellvertretern
Basistechniken (2) zVerteilte Garbage Collection yLöschung erst, wenn weder lokale noch entfernte Referenz auf Objekte existieren zAusnahmebehandlung yWeiterleitung von Ausnahmen, die bei einem entfernten Objekt auftreten, an ein lokales Objekt zNamensdienst yBekanntmachung von entfernten Objekten über Namen
Ergänzende Techniken zObjektmigration zMobile Agenten zApplet-zu-Applet-Kommunikation zGruppenkommunikation (Multicast) zAktivierung von Objekten aus DB zDatenbankunabhängige verteilte Persistenz
Voyager-Laufzeitumgebung zLaufzeitumgebung starten: Voyager.startup(String port) yauch: sun> voyager zQuellcode nachladen: VoyagerClassLoader.addResourceLoader(String URL) yauch: sun> voyager c file://usr/local/www/classes/ y lin> voyager c zIntegrierter HTTP-Server: ClassManager.enableResourceServer() yauch: sun> voyager r win> voyager c
Entfernte Objekte zErzeugung von Proxies zur Laufzeit ynicht wie bei RMI zur Übersetzungszeit vorbereitet yähnlich wie bei RMI über lokalen Stellvertreter (Proxy) reference invocation proxy local invocation Proxy.of("B") B reference invocation proxy local invocation Proxy.of("B") B
Beispiel: Baseball mit Voyager zpublic class Ball { ypublic void hit() { System.out.println("Ball has been hit") }} zpublic interface IBall { ypublic void hit(); } zpublic class Ball implements IBall, Serializable {... } zTool zur Erzeugung von Interfaces: igen
Typkompatibles Proxy zu Interface erzeugen zLokale Erzeugung yProxy.of(Object obj) zNamensdienst yNamespace.bind("8000/Ball", iball) zEntfernte Erzeugung yFactory.create(String classname, String url) zBeispiel: yBall ball = new Ball(); yIBall iball = (IBall) Proxy.of(ball) yIBall iball = (IBall) Factory.create("Ball", "sun:8000")
Fortsetzung des Beispiels zimport com.objectspace.voyager.*; zpublic class Bat { ypublic void play(IBall ball) { ball.hit() } ypublic static void main(String args[]) { try { Voyager.startup(); Bat bat = new Bat; IBall ball = (IBall) Factory.create("Ball","sun:8000"); bat.play(ball); } catch (... ) {... } Voyager.shutdown(); } } Konstruktor ohne Argument
Entfernte Konstruktoren mit Argumenten zObject[] arguments = new Object[]{new Integer(5)}; zIBall ball = (IBall) Factory.create("Ball", arguments, "sun:8000"); Konstruktor mit Argumente
Objektmigration (1) zAnwendungsgebiete: yZeitaufwand minimieren yLastbalancierung yBesitz- oder Verantwortungswechsel yMobile Geräte (bzw. nicht-permanent verfügbare Geräte)
Objektmigration (2) zEntfernter Zugriff vs. Migration
Objektmigration (3) zProtokoll für die Migration ytry { y IMobility mobileObj = MobilityOf(a); y mobileObj.moveTo("vodka.fh-wedel.de:8000"); y} catch (MobilityException e) { y... }
Probleme bei der Migration (1) zMigration durch Kopie simulieren? zDurch Migration muß Identität erhalten bleiben zLaufzeitumgebung stellt Korrektheit von "alten" Referenzen auf migrierte Objekte sicher D dA a IC cA aC c sunlinmac
Probleme bei der Migration (1) zMigration durch Kopie simulieren? zDurch Migration muß Identität erhalten bleiben zLaufzeitumgebung stellt Korrektheit von alten Referenzen auf migrierte Objekte sicher D dA a IC c A aC c sunlinmac A a C c
Probleme bei der Migration (2) zWas passiert mit referenzierten Objekten? zKopiersemantik zEventuell problematisch für "normale" Objekte zUnproblematisch für referenzierte Proxies D dA a IC cA aC c sunlinmac
Probleme bei der Migration (2) zWas passiert mit referenzierten Objekten? zKopiersemantik zEventuell problematisch für "normale" Objekte zUnproblematisch für referenzierte Proxies D d IC cA aC c sunlinmac A a IC cA a
Behandlung laufender Aufrufe zimport java.io.*; zpublic class Ball implements IBall, Serializable { ysynchronized public void hit() { System.out.println("Ball has been hit") } z}
Gruppenkommunikation zMulticast oder Publish-Subscribe-Mechanismus zVoyager spaces and subspaces ySubspace localSubspace = new Subspace() zEntfernter Zugriff über Namensraum yIsubspace remoteSubspace = (Isubspace) Namespace.lookup("//sun:9000/Subspace"); localSubspace.connect(remoteSubspace); ylocalSubspace.add(client);
Räume und Unterräume Space Rechner Subspace sunlin winmacnt Verknüpfung
Verteilung von Nachrichten im Unterraum zObject[] parameter = new Object[]{param}; zMulticast.invoke(subspace, "message", parameter, "Class"); zoder: IClass mcastProxy = localSubspace.getMulticastProxy("Class"); z mcastProxy.message(param); sun Nachricht Rechner Objekt Subspace
Mobile Agenten: Kommunikationsschema zOhne Agenten vs. mit Agenten
Bewegung und Aktion von Agenten zVorher: Explizite Migration von Objeken (Unterstützung der Methode moveTo) zAus welcher Motivation heraus werden Agenten bewegt? z"Eigeninitiative!" zBDI-Architektur yBeliefs yDesires yIntentions Wie kann man denn das hinkriegen???
Mobile Agenten: Einsatzgebiete zVerteilte Informationssuche zBörsenbeobachter zElektronischer Preisvergleich zMehrwertleistungen zJust-in-Time-Produktion
Mobile Agenten: Bewertung zVorteile: yReduktion der Netzwerklast yMöglichkeiten zum Offline-Gehen des Auftraggebers während der Agent aktiv ist yFlexiblere Reaktion auf Umgebung möglich als z.B. RMI zNachteile: yKomplexität der Programmierung/Erstellung yInfrastruktur erforderlich ySicherheitsprobleme (für Agenten und für jeweilige Wirtsumgebung)
Dienste in einer Umgebung Internet gateway PDA service Music service Discovery Alarm Camera Guests devices Laptop TV/PC Hotel wireless network
Diensterbringung durch Server
Konfigurierungsproblematik
Spontane Vernetzung zEintreten in eine Gruppe zDienste anbieten / anmelden für Gruppe zNachfrage nach Diensten einer Gruppe zMit einem Dienstinteressenten in Kontakt treten zKonkreten Dienst für bestimmte Zeit zusagen zKein Fehler: sich einfach entfernen, wenn gerade keiner auf eine konkrete Diensterbringung wartet zkein Fehler: sich einfach entfernen, wenn die Zeit für zugesagte Dienste abgelaufen ist zFehler: zugesagten Dienst nicht erbringen
Jini: Registrierung
Jini: Lookup und Leasing
Was ist eine Gruppe / Föderation?
Multicast Request: Service Announcement zDatagramm-Paket auf und Port 4160 Client Lookup Service Provider Service Objekt Service Attributes Nicht über Router geleitet
Multicast Request: Service Announcement zDatagramm-Paket auf und Port 4160 Client Lookup Service Provider Service Objekt Service Attribute Service Proxy Service Attribute
Multicast Request: Service Discovery zDatagramm-Paket auf und Port 4160 Client Lookup Service Provider Service Objekt Service Attributes Service Proxy Service Attributes
Multicast Request: Service Discovery zDatagramm-Paket auf und Port 4160 Client Lookup Service Provider Service Objekt Service Attributes Service Proxy Service Attributes Service Proxy
Multicast Request: Lookup Announcement zDatagramm-Paket auf und Port 4160 Lookup Service Nicht über Router geleitet
Softwarepakete in Java zimport java.rmi.*; zimport java.rmi.server.*; zimport net.jini.core.lookup.*; zimport sun.com.jini.lookup.*; zimport sun.com.jini.lease.*; siehe: Java in verteilten Systemen Marko Boger
Dienste: Beispiel Baseball zpublic class Ball extends UnicastRemoteObject implements RemoteBall ServiceIDListener { ypublic Ball throws RemoteException { super(); } ypublic void serviceIdNotify(ServiceID id) { System.out.println("ServiceId is " + id); } ypublic hit() { System.out.println("Ball has been hit.") } z}
Das Interface RemoteBall zimport java.rmi.* zpublic interface RemoteBall extends Remote { ypublic void hit() throws RemoteException; z}
Das Anmelden von Diensten (1) zKlasse JoinManager und entspr. Konstruktor zÜbergabe des als Service angebotenen Objekts, zdessen Beschreibung, zeines Callback-Objektes und zeines Leasing Managers:
Das Anmelden von Diensten (2) zpublic class BallStarter { ypublic static void main(String[] args) { try { xSystem.setSecurityManager(new RMISecurityManager ()); xRemoteBall ball = (RemoteBall) new Ball(); xLeaseRenewalManager renewal = new LeaseRenewalManager(); xEntry[] attributes = new Entry[]{ new Name("Jini enabled ball") }; xJoinManager join = new JoinManager(ball, attributes, (Ball) ball, renewal); xSystem.out.println("Ball started and registered at Lookup-Server"); y} catch (Exception e) { e.printStackTrace(); } y} z}
Lookup von Diensten: Suche durch Muster zKlasse ServiceTemplate und entspr. Konstruktor zÜbergabe an Konstruktor entweder yeines ServiceID-Objekts yoder einer Service-Beschreibung: xeiner Menge von Klassen xoder einer Menge von Attribut-Wert-Paaren yBeispiel mit Service-Beschreibung als Klasse: xClass[] classes = new Class[] { RemoteBall.class }; xServiceTemplate template = new ServiceTemplate(null, classes, null);
Zugriff auf den Dienstvermittler zRepräsentation des Dienstvermittlers als Objekt zDienstvermittler enthält Registratur zSuchmuster wird an Registratur übergeben zBeispiel: yLookupLocator l = new LookupLocator("jini://sun"); yServiceRegistrar r = l.getRegistrar(); yRemoteBall = b = (RemoteBall) r.lookup(template);
Aufruf eines Dienstes (1) zimport java.rmi.* zimport net.jini.core.discovery.*; zimport net.jini.core.lookup.*; zpublic class Bat { ypublic void play(RemoteBall ball) { try { ball.hit(); System.out.println("I hit the ball"); } catch (RemoteException e) { System.out.println(e) } }
Aufruf eines Dienstes (2) ypublic static void main(String[] args) { xBat bat = new Bat(); xtry { System.setSecurityManager(new RMI SecurityManager ()); x LookupLocator locator = new LookupLocator("jini://sun"); x ServiceRegistrar registrar = locator.getRegistrar(); x Class[] classes = new Class { RemoteBall.class }; x ServiceTemplate template = new ServiceTemplate(null, classes, null); x RemoteBall remoteBall = (RemoteBall) registrar.lookup(template); x bat.play(remoteBall); x} catch (Exception e) { x e.printStackTrace(); x} y}}
Starten und Aufrufen eines Dienstes zHTTP-Server, RMI-Daemon und Jini Lookup-Server starten yjava -cp /usr/remote/java/jini1_0/lib/jini-examples.jar com.sun.jini.example.service.StartService zServer: ysun> java -Djava.rmi.server.codebase= - Djava.security.policy=/jini1_0/batball/policy.all BallStarter ysun| Ball started an registered at Lookup-Server ysun| ServiceId is f7a17bde-e40b-42cb-94d4-bb6d37a999b8 zClient: ylin> java -Djava.security.policy=/jini1_0/batball/policy.all Bat ysun| Ball has been hit ylin| I hit the ball
Leasing zpublic interface Lease { ylong getExpiration(); yvoid renew (long duration) throws LeaseDeniedException, UnknownLeaseException, RemoteException; yvoid cancel() throws UnknownLeaseException, RemoteException; z} zVorher verwendete Klasse LeaseRenewalManager erneuert Leasing-Verträge automatisch
Auch beim nächsten Mal... z... gibt's wieder Neues in der Diskussion über Middleware yDatenbankanschluß (JDBC) yKomponentenorientierte Softwarekonstruktion (Beans) yMultitier-Architekturen (J2EE) xEnterprise Java Beans xServlets, Java Server Pages xXML