Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Vs8.1.5 1 8.1.5 Java RMI – Remote Method Invocation (http://java.sun.com/products/jdk/rmi )http://java.sun.com/products/jdk/rmi (http://java.sun.com/j2se/1.5/docs/guide/rmi.

Ähnliche Präsentationen


Präsentation zum Thema: "Vs8.1.5 1 8.1.5 Java RMI – Remote Method Invocation (http://java.sun.com/products/jdk/rmi )http://java.sun.com/products/jdk/rmi (http://java.sun.com/j2se/1.5/docs/guide/rmi."—  Präsentation transkript:

1 vs8.1.5 1 8.1.5 Java RMI – Remote Method Invocation (http://java.sun.com/products/jdk/rmi )http://java.sun.com/products/jdk/rmi (http://java.sun.com/j2se/1.5/docs/guide/rmi )http://java.sun.com/j2se/1.5/docs/guide/rmi (http://java.sun.com/docs/books/tutorial/rmi )http://java.sun.com/docs/books/tutorial/rmi (http://java.sun.com/developer/onlineTraining/rmi/RMI.html )http://java.sun.com/developer/onlineTraining/rmi/RMI.html Unterstützung von Fernaufrufen durch Bibliothekspakete java.rmi java.rmi.server java.rmi.registry und weitere... RMI bietet leider nur begrenzte Verteilungsabstraktion.

2 vs8.1.5 2  interface Remote Für ein fernaufrufbares Objekt und sein Vertreterobjekt muss eine gemeinsame Schnittstelle definiert werden, die von java.rmi.Remote erben muss, z.B. import java.rmi.*; interface RemoteService extends Remote { String echo(String s) throws RemoteException; } Spätere Vertretererzeugung gelingt nur dann, wenn die Ausnahme java.rmi.RemoteException vereinbart wird. 8.1.5.1 Grundzüge der Fernaufruf-Programmierung in Java

3 vs8.1.5 3  class UnicastRemoteObject Klasse eines fernaufrufbaren Objekts muss von java.rmi.server.UnicastRemoteObject erben, z.B. import java.rmi.*; import java.rmi.server.*; class Server extends UnicastRemoteObject implements RemoteService { public Server() throws RemoteException { } nötig! private String memory = ""; public String echo(String s) // throws entbehrlich! { return memory += s; } } UnicastRemoteObject redefiniert die Operationen von Object (z.B. equals() für Fernvergleich) und registriert das fernaufrufbare Objekt bei der RMI-Verwaltung (≈ Adapter). Achtung: Ein Server -Objekt kann durchaus auch lokal benutzt werden.

4 vs8.1.5 4  class Naming: Namensdienst ist über statische Operationen der Klasse java.rmi.Naming erreichbar: public static void rebind(String name, Remote object) throws RemoteException, MalformedURLException // java.net public static Remote lookup(String name) throws NotBoundException, RemoteException, MalformedURLException (weitere Operationen: bind, unbind, list )

5 vs8.1.5 5 Der Parameter String name ist im URL-Format anzugeben – er identifiziert Station und Port des Namensdienstes und enthält den eigentlichen Objektnamen: [ // host [ : port ] / ] name Adresse des Namensdienstes Standard-Host = lokale Station Standard-Port = 1099 Ein Namensdienst wird (unter Unix) gestartet mit rmiregistry [ port ] & (und sollte – wenn nicht mehr benötigt – mit kill beendet werden) Achtung: Einträge verändern nur lokal, aber abfragen auch entfernt !

6 vs8.1.5 6 Anbieterseitig: Server -Objekt erzeugen und beim (lokalen) Namensdienst registrieren: Naming.rebind("Service", new Server()); Casting erforderlich! Es wird geprüft, ob das von lookup gelieferte Vertreterobjekt tatsächlich die benötigte Schnittstelle implementiert. Klientenseitig: Klient erfragt Objekt beim Namensdienst: RemoteService s = (RemoteService)Naming.lookup("//obelix/Service"); System.out.println(s.echo("bla"); Aufsetzten und Verwendung

7 vs8.1.5 7 8.1.5.2 Vertretererzeugung und -installation (< JDK 1.5) Vertretergenerator heißt RMI Compiler und wird aufgerufen mit rmic also z.B. rmic Server ( - nicht mit Schnittstelle RemoteService !) und generiert Stubs – bereits als.class -Dateien EingabeAusgabe Server_Stub.class (Vertreter) Server.class Server_Skel.class ( Treiber)

8 vs8.1.5 8 Installation der.class -Dateien: CLASSPATH geeignet setzen!  Beim Erzeugen des fernaufrufbaren Objekts muss der zugehörige Treiber-Code greifbar sein.  Beim Registrieren des fernaufrufbaren Objekts beim Namensdienst muss auch der zugehörige Vertreter-Code greifbar sein - ferner: codebase wird dem Namensdienst zur späteren Weitergabe mitgeteilt (s.u.  ).  Beim Erzeugen des Vertreter-Objekts beim Klienten – als Folge der Anfrage beim Namensdienst – muss dort der Vertreter-Code greifbar sein. (Alternative: Namensdienst liefert codebase des Vertreter-Objekts – Security Manager muss das Herunterladen erlauben; vgl. 8.1.5.6)

9 vs8.1.5 9 8.1.5.3 Von der Programmierung bis zur verteilten Ausführung // RemoteService.java – sowohl für Client als auch Server interface RemoteService extends Remote { String echo(String s) throws RemoteException; } // Server.java class Server extends UnicastRemoteObject implements RemoteService { public Server() throws RemoteException { } private String memory = ""; public String echo(String s) { return memory += s+" "; } public static void main(String[] arg) throws Exception { Naming.rebind("Service", new Server()); // Programm stoppt hier nicht – wegen verborgener RMI Threads }

10 vs8.1.5 10 Übersetzen auf Server-Maschine obelix : javac RemoteService.java liefert RemoteService.class javac Server.java liefert Server.class Erzeugung der Stubs (optional*): rmic Server liefert Server_Stub.class Server_Skel.class Namensdienst einrichten (falls nicht schon vorhanden): rmiregistry & Server starten (er registriert sich selbst beim Namensdienst): java Server &

11 vs8.1.5 11 … und hier ein Beispiel-Klient: // Client.java, benötigt RemoteService.java class Client { public static void main(String[] arg) throws Exception { RemoteService s = (RemoteService)Naming.lookup("//"+arg[0]+"/Service"); System.out.println(s.echo(arg[1])+"\n"); System.exit(0); } Damit das Programm nicht Fernaufrufe wegen der RMI Threads hängenbleibt

12 vs8.1.5 12 Übersetzen auf irgendeiner Klienten-Maschine: javac RemoteService.java javac Client.java Vertreter-Code bereitstellen, Server_Stub.class, über Netzdateisystem oder Dateiübertragung von Server-Maschine obelix Klient z.B. wiederholt starten: > java Client obelix hallo hallo > java Client obelix hallo hallo > java Client obelix hallo hallo hallo hallo

13 vs8.1.5 13 Alternatives Szenario mit separater Entwickler-Station: Entwickler-StationKlienten-StationAnbieter-Station > javac RemoteService.java > javac Server.java > javac Client.java > rmic Server RemoteService.class RemoteService.class RemoteService.classServer.class Client.class Server_Stub.classServer_Stub.class Server_Stub.classServer_Skel.class > rmiregistry & > java Server & > java Client elfe bla bla >

14 vs8.1.5 14 Mit JDK 1.5 wird der Generator rmic nicht mehr unbedingt benötigt. Stattdessen kommt Java Reflection zum Einsatz. Zur Erinnerung: // Dynamischer Aufruf Class[] types = { String.class, Integer.class }; Method method = MyClass.getDeclaredMethod("myMethod", types); Object[] args = { "Hallo", new Integer(42) }; method.invoke(obj, args); // Dynamischer Proxy public interface Foo { public void bar(); } public class MyHandler implements InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) { if (method.getName().equals("bar"))... } }; Class[] interfaces = { Foo.class }; Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), interfaces, handler); f.bar(); // -> handler.invoke(...)

15 vs8.1.5 15 8.1.5.4 Verweise in Fernaufruf-Parametern Übergeben wird entweder Vertreter oder Kopie des Objekts:  Schnittstelle des formalen Parameters erbt von Remote : aktueller Parameter muss (statisch) gleiche Schnittstelle implementieren, (dynamisch) von UnicastRemoteObject erben, andernfalls MarshalingException  Netzverweis/Vertreterobjekt wird übergeben

16 vs8.1.5 16  Schnittstelle des formalen Parameters erbt nicht von Remote : aktueller Parameter muss (statisch) gleiche Schnittstelle implementieren, (dynamisch) Schnittstelle java.io.Serializable implementieren, andernfalls MarshalingException  Objektkopie wird übergeben In Objekte eingebettete Verweise werden entsprechend behandelt ! Felder (arrays) und Zeichenketten (strings) sind serializable !

17 vs8.1.5 17 Achtung! Wenn ein formaler Parameter einen Schnittstellentyp hat, kennt man vom aktuellen Parameter nur diese Schnittstelle (unabhängig davon, ob es sich um einem lokalen oder einen Fernaufruf handelt). ● Wird ein fernaufrufbares UnicastRemoteObject übergeben, so weiß man nicht, ob das Objekt tatsächlich entfernt oder aber lokal vorliegt. ● Handelt es sich um ein serialisierbares Objekt, so wird in Abhängigkeit von seiner Lage entweder eine Kopie oder das Objekt selbst geliefert!  Die Semantik des Aufrufs ist nicht eindeutig bestimmt ! (siehe dazu auch Brose/Löhr/Spiegel: Java resists transparent distribution)Java resists transparent distribution

18 vs8.1.5 18 8.1.5.5 Aktivierbare Objekte werden erst bei Bedarf erzeugt – allerdings nach vorangegangener Registrierung über den RMI Daemon rmid import java.rmi.activation.*; class Server extends Activatable implements RemoteService {............ public Server(ActivationID id, MarshalledObject data) throws RemoteException { super(id, 0); } } Server.class muss bei rmid, die zugehörige Vertreterklasse beim Namensdienst registriert werden – dafür muss ein setup-Programm geschrieben werden. http://java.sun.com/j2se/1.5.0/docs/guide/rmi/activation/overview.html

19 vs8.1.5 19 8.1.5.6 Dynamisches Nachladen von Code Stationen müssen den Code von Vertreter-Objekten (Remote) oder sogar Implementierungen (Serializable) kennen! Java-Code ist plattformunabhängig, kann über das Netz nachgeladen werden (via HTTP, FTP,...) Für jedes Programm, das Code nachladen muss ( rmiregistry, Client ): ● Security-Manager am Anfang des Programms festlegen: System.setSecurityManager(new RMISecurityManager()); ● Socket-Verwendung in policy -Datei gewähren grant { permission java.net.SocketPermission "*", "accept,connect,listen,resolve"; }; (in ~/.java.policy oder mit -Djava.security.policy=... )

20 vs8.1.5 20 Für jedes Programm, das nachladbaren Code anbietet ( Server ): ● Klassen oder JAR auf Web-Server bereitstellen: http://myhost.de/RemoteService.jar (enthält RemoteService.class, Server_Stub.class ) ● Codebase des Servers beim Start mit angeben: java -Djava.rmi.server.codebase= "http://myhost.de/RemoteService.jar" Server & Die Codebase-URL wird bei der rmiregistry hinterlegt. Klienten erhalten bei lookup nicht nur einen Netzverweis, sondern auch die zugehörige Codebase-URL, und laden den Code von dort nach. [Siehe http://java.sun.com/j2se/1.5.0/docs/guide/rmi/codebase.html]http://java.sun.com/j2se/1.5.0/docs/guide/rmi/codebase.html


Herunterladen ppt "Vs8.1.5 1 8.1.5 Java RMI – Remote Method Invocation (http://java.sun.com/products/jdk/rmi )http://java.sun.com/products/jdk/rmi (http://java.sun.com/j2se/1.5/docs/guide/rmi."

Ähnliche Präsentationen


Google-Anzeigen