Java RMI Áttekintés Miskolci Egyetem Általános Informatikai Tanszék Utolsó módosítás: 2008. 03. 05. javarmi / 1
A Java RMI RPC - egy távoli eljárás hívása helyi hívásnak tűnik RMI - hasonló mechanizmust biztosít, de objektum orientált módon: egy távoli objektum metódusának hívása helyi objektum használatának tűnik A Java nyelvnek nincs speciális IDL-je, ehelyett minden remote interface a java.rmi.remote interface-t terjeszti ki Java RMI (Áttekintés) javarmi / 2
A Java RMI architekt ktúrája Alkalmazás Client Server Stubs Skeletons Remote Reference Layer Transport Layer Java RMI (Áttekintés) javarmi / 3
Az RMI architekt ktúra elemei Stubs A kliens hivatkozása a távoli objektumra valójában hivatkozás a helyi csonkra. A csonk meghívja a Remote Reference Layer-t átalakítja (marshals) az argumentumokat értesíti a Remote Reference Layer-t hogy a hívás továbbítható visszaalakítja (unmarshals) a visszatérési értéket vagy a kivételt értesíti a Remote Reference Layer-t, hogy a hívás befejeződött. Java RMI (Áttekintés) javarmi / 4
Az RMI architekt ktúra elemei (folyt.) Skeleton Tartalmaz egy metódust, amely továbbítja a hívásokat az aktuális távoli objektumok implementációjának: visszaalakítja (unmarshals) az argumentumokat meghívja az aktuális távoli objektum implementációját átalakítja (marshals) a visszatérési értéket vagy a kivételt Java RMI (Áttekintés) javarmi / 5
Az RMI architekt ktúra elemei (folyt.) Remote reference layer A specifikus távoli hivatkozás protokoll végrehajtásáért felelős. Minden távoli objektum saját távoli hivatkozás osztályt választ, amely a kéréseit végrehajtja. Számos hívási protokoll választható ebben a rétegben. Például: unicast point-to-point invocation invocation to replicated object groups support for a specific replication strategy support for a persistent reference to the remote object (enabling activation of the remote objectum) reconnection strategies Java RMI (Áttekintés) javarmi / 6
Az RMI architekt ktúra elemei (folyt.) Transport layer A távoli címtartománnyal való kapcsolat létrehozása A kapcsolat menedzselése A kapcsolat "élő" voltának figyelése A bejövő hívások figyelése Az címtartományhoz tartozó távoli objektumok táblázatának karbantartása Kapcsolat létrehozása egy bejövő híváshoz A távoli hívás céljának megfelelő elosztó (dispatcher) megkeresése és a kapcsolat átadása a dispatcher-nek. Java RMI (Áttekintés) javarmi / 7
Az RMI egyéb b jellemzői Fonál használat az RMI-ben A szerver külön szálban, vagy azonos szálban is futhat Szemétgyűjtő mechanizmus a távoli objektumokra is Dinamikus osztálybetöltés Remote objektumok és interface-eik osztályára Stub és skeleton osztályokra Egyéb, az RMI által használt osztályokra (paraméterek, visszatérési értékek) Java RMI (Áttekintés) javarmi / 8
9 RMI kliens és s szerver fejlesztése se 7 Kliens implementálása (.java) Kliens indítása 1 Remote interface definiálása uses User 2 Interface implementálása (.java) 3 javac 3a rmic 8 javac Kliens stub 4 Kliens alk. (.class) (.class) 5 : csak 1.4-ig! 6 User feladata Generált elem Program feladata Manuális tev. Szerver osztály (.class) Szerver skeleton (.class) Jelölés RMI registry indítása Szerver objektum aktivizálása Távoli objektum regisztrálása Java RMI (Áttekintés) javarmi / 9
A fejlesztés s lépéseil 1. A távoli interface definiálása A távoli objektum interface-ének definiálása Java interface-ként A java.rmi.remote interface-t kell kiterjesztenie Minden metódusának dobnia kell a java.rmi.remoteexception kivételt. Java RMI (Áttekintés) javarmi / 10
A fejlesztés s lépései l (folyt.) 2. A távoli interface implementálása Az előbbi interface-t kell implementálnia 1.5 előtti verziók esetén a java.rmi.unicastremoteobject osztály leszármazottja kell legyen Az 5. verziótól kezdve ez nem szükséges A szerver osztályt példányosítani kell egy main metódusban. Ez lehet ugyanabban az osztályban, vagy egy másikban. A szerver objektumot exportálni kell (leszármazott esetén nem kell.) Java RMI (Áttekintés) javarmi / 11
A fejlesztés s lépései l (folyt.) 3. A szerver osztály lefordítása 3a. A stub compiler futtatása (csak 5. előtti verziók esetén!) A neve rmic, paraméterei azonosak a javac-vel Generálja a kliens stub-ot és a szerver skeletont. Az 5. verziótól kezdve nem szükséges. Java RMI (Áttekintés) javarmi / 12
A fejlesztés s lépései l (folyt.) 4. RMI registry indítása rmiregistry parancs a szerver gépen Lehetővé teszi a távoli objektum név szerinti elérését Ez is távoli objektumként van implementálva Minden szerver processz használhat saját registry-t vagy egy közöset A registry kezdetben üres, a távoli objektumokat a szerver processz(ek)nek kell bejegyeznie Java RMI (Áttekintés) javarmi / 13
A fejlesztés s lépései l (folyt.) 5. Szerver processz indítása A szerver processz létrehozza a szerver objektum példányát vagy példányait 6. Távoli objektumok regisztrációja A szerver processz bejegyzi a távoli objektumokat a registry-be Ehhez a java.rmi.naming osztály metódusait használhatja A szerver ezzel kész fogadni a kliensek kapcsolódását Java RMI (Áttekintés) javarmi / 14
A fejlesztés s lépései l (folyt.) 7. Kliens kód megírása A távoli objektum megkereséséhez használnia kell a java.rmi.naming osztály metódusait A távoli objektum használata ezután ugyanolyan, mint a lokális objektumoké 8 Kliens kód lefordítása 9. Kliens indítása Java RMI (Áttekintés) javarmi / 15
RMI interface-ek ek és s osztályok RMI-vel kapcsolatos csomagok (több, mint 25 osztály és interface): java.rmi java.rmi.server java.rmi.dgc java.rmi.registry Három funkcionális kategória: RMI alapok RMI security RMI marshalling Java RMI (Áttekintés) javarmi / 16
RMI alap osztályok és interface-ek ek Object osztály (from java.lang) IOExcept ion oszt ály (from Java.io) Remote (from java.rmi) <<implements>> RemoteStub (f ro m j ava.r m i. se rv er) RemoteObject (from java.rmi.server) RemoteObject() equals() tostring() RemoteServer (from java.rmi.server) RemoteException (from java.rmi) RemoteException() getmessage() <<uses>> RemoteStub() setref() RemoteServer() getclienthost() getlog() setlog() UnicastRemoteObject (from ja va.rmi. serve r) Kliens osztály Szerver osztály Unicas tremoteobject() exportobject() clone() Java RMI (Áttekintés) javarmi / 17
RMI alap osztályok feladata Remote interface Nincs egyetlen metódusa sem. Csak jelző. Minden remote objektumnak implementálnia kell RemoteObject osztály A Java Object osztály szerepét tölti be a távoli objektumokra RemoteStub osztály A kliens objektum(ok) közvetlen ősosztálya Elrejti a szerver objektummal való kapcsolatot az őt használó objektumok elől. Java RMI (Áttekintés) javarmi / 18
RMI alap osztályok feladata (folyt.) RemoteServer osztály Szerver objektumok létrehozása és exportálása (elérhetővé tétele) A szerver implementációk közös bázisosztálya UnicastRemoteObject osztály A távoli szerver objektum implementációja, az alábbi tulajdonságokkal: Tranziens objektum összeköttetés alapú TCP protokollt használ a kommunikációra Az 1.5-nál régebbi verziók esetén a szerver osztály ősosztálya kell legyen Java RMI (Áttekintés) javarmi / 19
RMI alap osztályok feladata (folyt.) RemoteException osztály Az RMI által kiváltható valamennyi kivétel ősosztálya A remote interface valamennyi metódusánál specifikálni kell Java RMI (Áttekintés) javarmi / 20
RMI Naming szolgáltat ltatás Object osztály (from java.lang) Remote (from java.rmi) Registry (from java.rmi.registry) lookup() bind() unbind() rebind() LocateRegistry (from java.rmi.registry) getregistry() createregistry() Naming (from java.rmi.registry) lookup() bind() unbind() rebind() list() Java RMI (Áttekintés) javarmi / 21
A naming szolgáltat ltatás s használata Többnyire csak a Naming osztályt használjuk. Azonosítás URL formátumú: rmi://host:port/objektumnev Default port: 1099 A kliens a lookup metódust használja a távoli objektum referencia megszerzésére: Remote lookup(string name) A szerver a bind vagy rebind metódust használja a szerver objektum regisztrálására: void bind(string name, Remote obj) Java RMI (Áttekintés) javarmi / 22
Az RMI forgatókönyve Kliens oldal Szerver oldal Kliens System Naming System Szerver 1. setsecuritymanager 2. rebind 3. setsecuritymanager 4. lookup Proxy szerver download 5. metódus hívás metódus hívás Java RMI (Áttekintés) javarmi / 23
Az RMI forgatókönyve (folyt.) 1. A szerver engedélyezi az RMI Security Manager működését: létrehoz egy új RMISecurityManager objektumot és átadja a System objektumnak 2. A szerver regisztrálja magát a névszolgáltatónál 3. A kliens is engedélyezi az RMI Security Managert a saját rendszerében Java RMI (Áttekintés) javarmi / 24
Az RMI forgatókönyve (folyt.) 4. A kliens megkeresi a távoli objektumot Kiad egy lookup hívást a Naming objektumnak, és megadja a kivánt szerver URL nevét A metódus visszad egy referenciát a proxy szerverre Ha szükséges, a kliens oldali stub letöltődik 5. A kliens meghívja a távoli objektum metódusát A hívás a proxy szerver objektumhoz fut be A proxy szerver továbbítja a hívást a stub segítségével A hívás eredménye visszaérkezik szintén a stub segítségével Java RMI (Áttekintés) javarmi / 25
Egyszerű példa Ebben a példában a távoli objektum egy számlálóval rendelkezik. A számláló adott értékre beállítható, inkrementálható, lekérdezhető. Egy kliens ezt a távoli objektumot használva nullázza a számlálót, ezerszer inkrementálja, majd lekérdezi az értékét. A szerver helye a kliens program paramétere. Java RMI (Áttekintés) javarmi / 26
Példa: távoli t interface A távoli objektum interface-e: public interface CountRMI extends java.rmi.remote { public int sum() throws java.rmi.remoteexception; public void sum(int val) throws java.rmi.remoteexception; public int increment() throws java.rmi.remoteexception; } Java RMI (Áttekintés) javarmi / 27
Példa: kliens program import java.rmi.*; import java.rmi.registry.*; import java.rmi.server.*; public class CountRMIClient { public static void main(string args[]) { // Security manager beállítása System.setSecurityManager(new RMISecurityManager()); Java RMI (Áttekintés) javarmi / 28
Példa: kliens program (folyt.) // Referencia szerzese a tavoli objektumra try { CountRMI mycount = (CountRMI)Naming.lookup("rmi://" + args[0] + "/" + "mycountrmi"); // Megjegyzesek: // a fenti castolas szukseges es lehetseges // innentol kezdve a mycount ugyanugy // hasznalhato, mint egy helyi referencia // szamlalo nullazasa System.out.println("Setting Sum to 0"); mycount.sum(0); // Mint egy helyi hivas Java RMI (Áttekintés) javarmi / 29
Példa: kliens program (folyt.) // Incrementalas 1000-szer System.out.println("Incrementing"); for (int i = 0 ; i < 1000 ; i++ ) { mycount.increment(); } System.out.println("Sum = " + mycount.sum()); // Kivetel kezelese } catch(exception e) } {System.err.println("System Exception" + e);} System.exit(0); } Java RMI (Áttekintés) javarmi / 30
Szerver objektum implementáci ciója import java.rmi.*; import java.rmi.server.unicastremoteobject; public class CountRMIImpl //csak 1.5 előtt! extends UnicastRemoteObject implements CountRMI { // Adattag private int sum; Java RMI (Áttekintés) javarmi / 31
Szerver objektum impl. (folyt.) public CountRMIImpl() { } Java RMI (Áttekintés) javarmi / 32
Szerver objektum impl. (folyt.) // Tavolrol is elerheto metodusok public int sum() throws RemoteException { return sum; } public void sum(int val) throws RemoteException { sum = val; } } public int increment() throws RemoteException { sum++; return sum; } Java RMI (Áttekintés) javarmi / 33
Szerver objektum inicializálása import java.rmi.*; import java.rmi.registry.*; import java.rmi.server.*; public class CountRMIServer { public static void main(string args[]) { // Security manager letrehozasa es inditasa System.setSecurityManager(new RMISecurityManager()); Java RMI (Áttekintés) javarmi / 34
Szerver objektum inicializálása (folyt.) try { // CountRMIImpl peldany letrehozasa CountRMIImpl mycount = new CountRMIImpl(); // mycount exportalasa CountRMI stub = (CountRMI) UnicastRemoteObject.exportObject(myCount, 0); // Bejegyzés a registry-be Registry registry = LocateRegistry.getRegistry(); registry.bind("mycountrmi", mycount); Java RMI (Áttekintés) javarmi / 35
Szerver objektum inicializálása (folyt.) } System.out.println("CountRMI Server ready."); } } catch (Exception e) { System.out.println("Exception: " + e.getmessage()); } e.printstacktrace(); Java RMI (Áttekintés) javarmi / 36
A példap futtatása Lefordítjuk az összes modult (feltételezve, hogy a java file-ok katalógusában vagyunk) javac cp. CountRMI.java javac cp. CountRMIClient.java javac cp. CountRMIImpl.java javac cp. CountRMIServer.java (5. előtti verziónál: Futatjuk a stub compilert rmic CountRMIImpl) Elindítjuk az RMI registry-t rmiregistry Elindítjuk a szervert majd a klienst Java RMI (Áttekintés) javarmi / 37
Hivatkozások Csizmazia Balázs: Hálózati alkalmazások készítése (második kiadás), 6. fejezet Kiadó: Kalibán Bt., Budapest. 1998 ISBN 963 03 5113 7 Sok szerző: JAVA 2 útikalauz programozóknak. (Hatodik kiadás) 21. Fejezet Kiadó: ELTE TTK Hallgatói Alapítvány Budapest, 2000 ISBN 963 463 364 1 Java RMI (Áttekintés) javarmi / 38
Hivatkozások (folyt.) Robert Orfali, Dan Harkey: Client/Sserver Programming with JAVA and CORBA (Second Edition) Chapter 13. John Wiley & Sons, 1998 ISBN 0 471 24578 X java.sun.com: RMI tutorial Java RMI (Áttekintés) javarmi / 39