Realisierung verteilter Anwendungen: Teil 4 Ralf Möller, FH-Wedel Beim vorigen Mal: RMI und Grundlagen von CORBA Inhalt heute Verteilung und Objektorientierung (Voyager) Spontane Vernetzung (Jini) Lernziele: Verständnis der Probleme und Lösungsansätze bei Objektmigration und spontaner Vernetzung Voyager Zu Java kompatible Laufzeitumgebung und Bibliothek, die auf eine umfassende Lösung für sehr viele Bereiche und Probleme der Programmierung verteilter Systeme zielt Funktions- und Leistungsumfang wächst mit jeder neuen Version In dieser Vorlesung nur grundlegende Techniken Basistechniken (1) Entfernte Objekte Erzeugung eines entfernten Objekts aus einem lokalen Objekt zur Laufzeit und zu jeder Java-Klasse Entfernte Referenzierung Transparente Referenzierung entfernter Objekte Typ: gemeinsames Interface Entfernte Erzeugung Erzeugung von Objekten in einer anderen VM (statt nur Erzeugung lokaler Objekte) Automatische Erzeugung von lokalen Stellvertretern Basistechniken (2) Verteilte Garbage Collection Löschung erst, wenn weder lokale noch entfernte Referenz auf Objekte existieren Ausnahmebehandlung Weiterleitung von Ausnahmen, die bei einem entfernten Objekt auftreten, an ein lokales Objekt Namensdienst Bekanntmachung von entfernten Objekten über Namen Ergänzende Techniken Objektmigration Mobile Agenten Applet-zu-Applet-Kommunikation Gruppenkommunikation (Multicast) Aktivierung von Objekten aus DB Datenbankunabhängige verteilte Persistenz Voyager-Laufzeitumgebung Laufzeitumgebung starten: Voyager.startup(String port) auch: sun> voyager <port> Quellcode nachladen: VoyagerClassLoader.addResourceLoader(String URL) auch: sun> voyager 8000 -c file://usr/local/www/classes/ lin> voyager 7000 -c http://www.fh-wedel.de/classes/ Integrierter HTTP-Server: ClassManager.enableResourceServer() auch: sun> voyager 8000 -r win> voyager 9000 -c http://sun.fh-wedel.de:8000/ Entfernte Objekte Erzeugung von Proxies zur Laufzeit nicht wie bei RMI zur Übersetzungszeit vorbereitet ähnlich wie bei RMI über lokalen Stellvertreter (Proxy) local invocation proxy reference local invocation Proxy.of("B") B proxy reference local invocation Proxy.of("B") local invocation B Beispiel: Baseball mit Voyager public class Ball { public void hit() { System.out.println("Ball has been hit") }} public interface IBall { public void hit(); } public class Ball implements IBall, Serializable { ... } Tool zur Erzeugung von Interfaces: igen Typkompatibles Proxy zu Interface erzeugen Lokale Erzeugung Proxy.of(Object obj) Namensdienst Namespace.bind("8000/Ball", iball) Entfernte Erzeugung Factory.create(String classname, String url) Beispiel: Ball ball = new Ball(); IBall iball = (IBall) Proxy.of(ball) IBall iball = (IBall) Factory.create("Ball", "sun:8000") Fortsetzung des Beispiels import com.objectspace.voyager.*; public class Bat { public void play(IBall ball) { ball.hit() } public static void main(String args[]) { Konstruktor try { ohne Voyager.startup(); Argument Bat bat = new Bat; IBall ball = (IBall) Factory.create("Ball","sun:8000"); bat.play(ball); } catch ( ... ) { ... } Voyager.shutdown(); } } Entfernte Konstruktoren mit Argumenten Object[] arguments = new Object[]{new Integer(5)}; IBall ball = (IBall) Factory.create("Ball", arguments, "sun:8000"); Konstruktor mit Argumente Objektmigration (1) Anwendungsgebiete: Zeitaufwand minimieren Lastbalancierung Besitz- oder Verantwortungswechsel Mobile Geräte (bzw. nicht-permanent verfügbare Geräte) Objektmigration (2) Entfernter Zugriff vs. Migration Objektmigration (3) Protokoll für die Migration try { IMobility mobileObj = MobilityOf(a); mobileObj.moveTo("vodka.fh-wedel.de:8000"); } catch (MobilityException e) { ... } Probleme bei der Migration (1) Migration durch Kopie simulieren? Durch Migration muß Identität erhalten bleiben Laufzeitumgebung stellt Korrektheit von "alten" Referenzen auf migrierte Objekte sicher sun Dd Aa lin mac Aa IC c Cc Probleme bei der Migration (1) Migration durch Kopie simulieren? Durch Migration muß Identität erhalten bleiben Laufzeitumgebung stellt Korrektheit von alten Referenzen auf migrierte Objekte sicher sun Dd Aa lin mac Aa IC c Cc Cc Aa Probleme bei der Migration (2) Was passiert mit referenzierten Objekten? Kopiersemantik Eventuell problematisch für "normale" Objekte Unproblematisch für referenzierte Proxies sun Dd Aa lin mac Aa IC c Cc Probleme bei der Migration (2) Was passiert mit referenzierten Objekten? Kopiersemantik Eventuell problematisch für "normale" Objekte Unproblematisch für referenzierte Proxies sun lin mac Dd Aa Aa IC c Cc Aa IC c Behandlung laufender Aufrufe import java.io.*; public class Ball implements IBall, Serializable { synchronized public void hit() { System.out.println("Ball has been hit") } } Gruppenkommunikation Multicast oder Publish-Subscribe-Mechanismus Voyager spaces and subspaces Subspace localSubspace = new Subspace() Entfernter Zugriff über Namensraum Isubspace remoteSubspace = (Isubspace) Namespace.lookup("//sun:9000/Subspace"); localSubspace.connect(remoteSubspace); localSubspace.add(client); Räume und Unterräume sun lin win Space mac Rechner nt Subspace Verknüpfung Verteilung von Nachrichten im Unterraum Rechner Nachricht Objekt sun Subspace Object[] parameter = new Object[]{param}; Multicast.invoke(subspace, "message", parameter, "Class"); oder: IClass mcastProxy = localSubspace.getMulticastProxy("Class"); mcastProxy.message(param); Mobile Agenten: Kommunikationsschema Ohne Agenten vs. mit Agenten Bewegung und Aktion von Agenten Vorher: Explizite Migration von Objeken (Unterstützung der Methode moveTo) Aus welcher Motivation heraus werden Agenten bewegt? "Eigeninitiative!" BDI-Architektur Beliefs Desires Intentions Wie kann man denn das hinkriegen??? Mobile Agenten: Einsatzgebiete Verteilte Informationssuche Börsenbeobachter Elektronischer Preisvergleich Mehrwertleistungen Just-in-Time-Produktion Mobile Agenten: Bewertung Vorteile: Reduktion der Netzwerklast Möglichkeiten zum Offline-Gehen des Auftraggebers während der Agent aktiv ist Flexiblere Reaktion auf Umgebung möglich als z.B. RMI Nachteile: Komplexität der Programmierung/Erstellung Infrastruktur erforderlich Sicherheitsprobleme (für Agenten und für jeweilige Wirtsumgebung) Dienste in einer Umgebung Music service gateway Alarm service Internet Hotel wireless network Discovery service Camera TV/PC Laptop PDA Guests devices Diensterbringung durch Server Konfigurierungsproblematik Spontane Vernetzung Eintreten in eine Gruppe Dienste anbieten / anmelden für Gruppe Nachfrage nach Diensten einer Gruppe Mit einem Dienstinteressenten in Kontakt treten Konkreten Dienst für bestimmte Zeit zusagen Kein Fehler: sich einfach entfernen, wenn gerade keiner auf eine konkrete Diensterbringung wartet kein Fehler: sich einfach entfernen, wenn die Zeit für zugesagte Dienste abgelaufen ist Fehler: zugesagten Dienst nicht erbringen Jini: Registrierung Jini: Lookup und Leasing Was ist eine Gruppe / Föderation? intranet ISP % % % % backbone satellite link desktop computer: server: network link: Was ist eine Gruppe / Föderation? email s erv er Desktop computers print and other servers Web server Local area netw ork email s erv er File s erv er print other servers the rest of the Internet router/firew all Multicast Request: Service Announcement Datagramm-Paket auf 224.0.1.85 und Port 4160 Lookup Service Client Nicht über Router geleitet Service Provider Service Objekt Service Attributes Multicast Request: Service Announcement Datagramm-Paket auf 224.0.1.85 und Port 4160 Lookup Service Service Proxy Service Attribute Client Service Provider Service Objekt Service Attribute Multicast Request: Service Discovery Datagramm-Paket auf 224.0.1.85 und Port 4160 Lookup Service Service Proxy Service Attributes Client Service Attributes Service Provider Service Objekt Service Attributes Multicast Request: Service Discovery Datagramm-Paket auf 224.0.1.85 und Port 4160 Lookup Service Service Proxy Service Attributes Client Service Provider Service Proxy Service Attributes Service Objekt Service Attributes Multicast Request: Lookup Announcement Datagramm-Paket auf 224.0.1.84 und Port 4160 Lookup Service Nicht über Router geleitet Softwarepakete in Java import import import import import java.rmi.*; java.rmi.server.*; net.jini.core.lookup.*; sun.com.jini.lookup.*; sun.com.jini.lease.*; siehe: Java in verteilten Systemen Marko Boger Dienste: Beispiel Baseball public class Ball extends UnicastRemoteObject implements RemoteBall ServiceIDListener { public Ball throws RemoteException { super(); } public void serviceIdNotify(ServiceID id) { System.out.println("ServiceId is " + id); } public hit() { System.out.println("Ball has been hit.") } } Das Interface RemoteBall import java.rmi.* public interface RemoteBall extends Remote { public void hit() throws RemoteException; } Das Anmelden von Diensten (1) Klasse JoinManager und entspr. Konstruktor Übergabe des als Service angebotenen Objekts, dessen Beschreibung, eines Callback-Objektes und eines Leasing Managers: Das Anmelden von Diensten (2) public class BallStarter { public static void main(String[] args) { try { System.setSecurityManager(new RMISecurityManager ()); RemoteBall ball = (RemoteBall) new Ball(); LeaseRenewalManager renewal = new LeaseRenewalManager(); Entry[] attributes = new Entry[]{ new Name("Jini enabled ball") }; JoinManager join = new JoinManager(ball, attributes, (Ball) ball, renewal); System.out.println("Ball started and registered at Lookup-Server"); } catch (Exception e) { e.printStackTrace(); } } } Lookup von Diensten: Suche durch Muster Klasse ServiceTemplate und entspr. Konstruktor Übergabe an Konstruktor entweder eines ServiceID-Objekts oder einer Service-Beschreibung: einer Menge von Klassen oder einer Menge von Attribut-Wert-Paaren Beispiel mit Service-Beschreibung als Klasse: Class[] classes = new Class[] { RemoteBall.class }; ServiceTemplate template = new ServiceTemplate(null, classes, null); Zugriff auf den Dienstvermittler Repräsentation des Dienstvermittlers als Objekt Dienstvermittler enthält Registratur Suchmuster wird an Registratur übergeben Beispiel: LookupLocator l = new LookupLocator("jini://sun"); ServiceRegistrar r = l.getRegistrar(); RemoteBall = b = (RemoteBall) r.lookup(template); Aufruf eines Dienstes (1) import java.rmi.* import net.jini.core.discovery.*; import net.jini.core.lookup.*; public class Bat { public 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) public static void main(String[] args) { Bat bat = new Bat(); try { System.setSecurityManager(new RMI SecurityManager ()); LookupLocator locator = new LookupLocator("jini://sun"); ServiceRegistrar registrar = locator.getRegistrar(); Class[] classes = new Class { RemoteBall.class }; ServiceTemplate template = new ServiceTemplate(null, classes, null); RemoteBall remoteBall = (RemoteBall) registrar.lookup(template); bat.play(remoteBall); } catch (Exception e) { e.printStackTrace(); } }} Starten und Aufrufen eines Dienstes HTTP-Server, RMI-Daemon und Jini Lookup-Server starten java -cp /usr/remote/java/jini1_0/lib/jini-examples.jar com.sun.jini.example.service.StartService Server: sun> java -Djava.rmi.server.codebase=http://localhost:8000/batBall/ Djava.security.policy=/jini1_0/batball/policy.all BallStarter sun| Ball started an registered at Lookup-Server sun| ServiceId is f7a17bde-e40b-42cb-94d4-bb6d37a999b8 Client: lin> java -Djava.security.policy=/jini1_0/batball/policy.all Bat sun| Ball has been hit lin| I hit the ball Leasing public interface Lease { long getExpiration(); void renew (long duration) throws LeaseDeniedException, UnknownLeaseException, RemoteException; void cancel() throws UnknownLeaseException, RemoteException; } Vorher verwendete Klasse LeaseRenewalManager erneuert Leasing-Verträge automatisch Auch beim nächsten Mal ... ... gibt's wieder Neues in der Diskussion über Middleware Datenbankanschluß (JDBC) Komponentenorientierte Softwarekonstruktion (Beans) Multitier-Architekturen (J2EE) Enterprise Java Beans Servlets, Java Server Pages XML