close

Vyvolání vzdálené metody Java

Přejít na navigaci Přejít na hledání

RMI ( Java Remote Method Invocation ) je mechanismus nabízený Java pro vzdálené vyvolání metody . Je součástí standardního běhového prostředí Java a poskytuje jednoduchý mechanismus pro serverovou komunikaci v distribuovaných aplikacích pouze Java. Pokud je vyžadována komunikace mezi jinými technologiemi, měly by být místo RMI použity CORBA nebo SOAP .

RMI se vyznačuje snadností použití v programování, protože je speciálně navrženo pro Javu; poskytuje předávání objektů odkazem (nepovoluje SOAP), distribuovaný sběr odpadu (Distributed Garbage Collector) a předávání libovolného typu (funkce není poskytována CORBA).

Prostřednictvím RMI může Java program exportovat objekt , zpřístupnit objekt přes síť a program čeká na požadavky na TCP portu . Poté se klient může připojit a vyvolat metody poskytované objektem.

Vyvolání se skládá z následujících kroků:

  • Zařazování parametrů (pomocí serializační funkce Java ).
  • Vyvolání metody (klienta na serveru). Volající čeká na odpověď.
  • Po dokončení spuštění server serializuje návratovou hodnotu (pokud existuje) a odešle ji klientovi.
  • Klientský kód obdrží odpověď a pokračuje, jako by bylo vyvolání lokální.

Kontext

Od verze JDK 1.1 má Java vlastní ORB : RMI (Remote Method Invocation). Ačkoli RMI je ORB v obecném smyslu, není to model vyhovující CORBA. RMI je nativní v Javě, to znamená, že je rozšířením základního jazyka. RMI zcela spoléhá na jádro Java Object Serialization, stejně jako implementaci přenositelnosti a mechanismů pro načítání a vyjímání objektů na jiných systémech atd.

Použití RMI je pro každého programátora Java velmi přirozené, protože se nemusí učit novou technologii zcela odlišnou od té, se kterou bude vyvíjet. RMI má však určitá omezení kvůli těsné integraci s Javou, hlavním z nich je, že tato technologie neumožňuje interakci s aplikacemi napsanými v jiném jazyce.

RMI, jako rozšíření Javy, je programovací technologie navržená k řešení problémů psaním a organizováním spustitelného kódu. RMI tak představuje specifický bod v prostoru programovacích technologií spolu s C, C++, Smalltalk atd.

Hlavní rozdíl mezi používáním RPC a RMI je v tom, že RMI je mechanismus pro vzdálené vyvolání procedur založený na programovacím jazyce Java, který podporuje interakci mezi objekty, zatímco RPC tuto funkci nepodporuje.

Architektura

Na architekturu RMI lze nahlížet jako na čtyřvrstvý model.

První vrstva

První vrstva je aplikační vrstva a odpovídá skutečné implementaci klientských a serverových aplikací. Zde probíhají volání na vysoké úrovni pro přístup a export vzdálených objektů. Jakákoli aplikace, která chce, aby její metody byly dostupné pro přístup vzdáleným klientům, musí tyto metody deklarovat v rozhraní , které rozšiřuje java.rmi.Remote. Takové rozhraní se v podstatě používá k „označení“ objektu jako vzdáleně přístupného. Jakmile jsou metody implementovány, musí být objekt exportován. To lze provést implicitně, pokud objekt rozšiřuje třídu UnicastRemoteObject (balíček java.rmi.server), nebo to lze provést explicitně voláním metody exportObject() stejného balíčku.

Druhá vrstva

Vrstva 2 je proxy vrstva nebo stub-skeleton vrstva. Tato vrstva je ta, která přímo interaguje s aplikační vrstvou. V této vrstvě probíhají všechna volání vzdálených objektů a akce spolu s jejich parametry a návratovými objekty.

Třetí vrstva

Vrstva 3 je vzdálená referenční vrstva a je zodpovědná za zpracování sémantické části vzdálených vyvolání. Je také odpovědný za správu replikace objektů a provádění úloh specifických pro implementaci se vzdálenými objekty, jako je vytvoření sémantické perzistence a správné strategie obnovy ze ztracených připojení. V této vrstvě se od transportní vrstvy očekává proudově orientované spojení.

Čtvrtá vrstva

Vrstva 4 je transportní vrstva. Je odpovědný za vytvoření nezbytných připojení a řízení přenosu dat z jednoho stroje do druhého. Základním transportním protokolem pro RMI je Java Remote Method Protocol (JRMP), kterému „rozumějí“ pouze programy Java.

Prvky

Každá aplikace RMI se normálně dělí na 2 části:

  • Server, který vytvoří nějaké vzdálené objekty, vytvoří odkazy, aby je zpřístupnil, a čeká, až je klient vyvolá.
  • Klient, který získá odkaz na vzdálené objekty na serveru a vyvolá je.

Příklad

Server RMI se skládá z definování vzdáleného objektu, který budou klienti používat. Chcete-li vytvořit vzdálený objekt, je definováno rozhraní a vzdáleným objektem bude třída, která toto rozhraní implementuje. Podívejme se, jak vytvořit ukázkový server ve 3 krocích:

  • Definujte vzdálené rozhraní. Když je vytvořeno vzdálené rozhraní:
    • Rozhraní musí být veřejné.
    • Musí zdědit z rozhraní java.rmi.Remote, aby bylo zřejmé, že jej lze volat z libovolného virtuálního stroje Java.
    • Každá vzdálená metoda musí ve své klauzuli throws vyvolat výjimku java.rmi.RemoteException, kromě všech výjimek, které dokáže zpracovat.
veřejné  rozhraní  MyRemoteInterface  rozšiřuje  java . rmi . Remote 
{ 
  public  void  myMethod1 ()  vyvolá  java . rmi . RemoteException ; 
  public  int  myMethod2 ()  vyvolá  java . rmi . RemoteException ; 
}
  • Implementujte vzdálené rozhraní
veřejná  třída  MyRemoteClass  
 rozšiřuje  java . rmi . server . UnicastRemoteObject  
 implementuje  MyRemoteInterface 
{ 
 public  MyRemoteClass ()  vyvolá  java . rmi . RemoteException 
 { 
   super ();  //Zavolání konstruktoru základní třídy (UnicastRemoteObject) 
   // Kód konstruktoru 
 }
 
 public  void  myMethod1 ()  vyvolá  java . rmi . RemoteException 
 { 
   // Sem vložíme požadovaný kód 
   System . ven . println ( "Jsem v myMethod1()" ); 
 }

 public  int  myMethod2 ()  vyvolá  java . rmi . RemoteException 
 { 
   return  5 ;  // Sem vložíme kód, který chceme 
 }

 public  void  otherMethod () 
 { 
   // Pokud definujeme jinou metodu, nelze ji volat 
   // vzdáleně, protože není ze vzdáleného rozhraní 
 }
 
 public  static  void  main ( String []  args ) 
 { 
   try 
   { 
     MyRemoteInterface  mir  =  new  MyRemoteClass (); 
     java . rmi . Pojmenování . rebind ( "rmi://"  +  java . net . InetAddress . getLocalHost (). getHostAddress ()  + 
                             ":"  +  args [ 0 ]  +  "/TestRMI" ,  mir ); 
   } 
   catch  ( výjimka  e ) 
   { 
     e . printStackTrace (); 
   } 
 } 
}
  • Jak můžete vidět, třída MyRemoteClass implementuje rozhraní MyRemoteInterface, které jsme dříve definovali. Také dědí z UnicastRemoteObject, což je třída Java, kterou můžeme použít jako nadtřídu k implementaci vzdálených objektů.
  • Pak uvnitř třídy definujeme konstruktor (který vyvolá výjimku RemoteException, protože je také vyvolána nadtřídou UnicastRemoteObject) a metody rozhraní, které implementuje.
  • Nakonec v hlavní metodě definujeme kód pro vytvoření vzdáleného objektu, který chceme sdílet, a zviditelníme vzdálený objekt pro klienty pomocí třídy Naming a její metody rebind(...).

Poznámka: Pro pohodlí jsme metodu main() umístili do stejné třídy. Mohla by být definována samostatná třída zodpovědná za registraci vzdáleného objektu.

  • Zkompilujte a spusťte server

Server již máme definovaný. Nyní musíme zkompilovat vaše třídy pomocí následujících kroků:

    • Zkompilujeme vzdálené rozhraní. Kromě toho jej seskupujeme do souboru JAR, aby byl přítomen na klientovi i na serveru:
javac MyRemoteInterface.java
jar cvf objRemotes.jar MyRemoteInterface.class
    • Dále zkompilujeme třídy, které implementují rozhraní. A pro každý z nich pomocí příkazu rmic vygenerujeme soubory Stub a Skeleton, abychom udrželi odkaz na vzdálený objekt:
nastavit CLASSPATH=%CLASSPATH%;.\Remoteobj.jar;.
javac MyRemoteClass.java
rmic -d . MyRemoteClass

V našem pracovním adresáři můžeme vidět, že byly automaticky vygenerovány dva soubory .class (MiClaseRemota_Skel.class a MiClaseRemota_Stub.class) odpovídající vrstvě stub-skeleton architektury RMI.

  • Chcete-li spustit server, postupujte takto:
    • Protokolování RMI je spuštěno, aby bylo možné protokolovat a vyhledávat vzdálené objekty. Registr má na starosti správu sady vzdálených objektů, které mají být sdíleny, a jejich vyhledávání na žádost klientů. Běží s aplikací rmiregistry distribuovanou s Javou, které můžeme volitelně předat port pro připojení (standardně 1099).

V případě Windows je nutné provést:

spusťte rmiregistr 1234

A v případě Linuxu:

rmiregistr &
    • Nakonec se server spustí:
java -Djava.rmi.server.hostname=127.0.0.1 MyRemoteClass 1234
  • Vytvořte klienta RMI

Nyní definujeme klienta, který bude přistupovat ke vzdáleným objektům, které vytvoříme. K tomu postupujeme podle následujících kroků:

    • Definujte třídu, abyste získali požadované vzdálené objekty

Následující třída získá objekt typu MyRemoteInterface, implementovaný na našem serveru:

public  class  MyRMIClient 
{

 private  MyRMIClient (){}; 

 public  static  void  main ( String []  args ) 
 { 
   try 
   { 
     MyRemoteInterface  mir  =  ( MyRemoteInterface ) java . rmi . Pojmenování . vyhledávání ( "rmi://"  +  
                             args [ 0 ]  +  ":"  +  args [ 1 ]  +  "/RMITest" );
     
     // Tisk myMethod1() tolikrát, kolikrát myMethod2() vrátí 
     pro  ( int  i = 1 ; i <= myr . myMethod2 (); i ++ )  
         myr . mojeMetoda1 (); 
   } 
   catch  ( výjimka  e ) 
   { 
     e . printStackTrace (); 
   } 
 } 
}

Jak vidíte, jednoduše se skládá z hledání vzdáleného objektu v registru RMI vzdáleného počítače. K tomu používáme třídu Naming a její metodu lookup(...).

    • Zkompilujte a spusťte klienta

Jakmile jsme již definovali klienta, pro jeho kompilaci provedeme:

nastavit CLASSPATH=%CLASSPATH%;.\Remoteobj.jar;.
javac MyRMIClient.java

Poté pro spuštění klienta provedeme:

java MyClientRMI 127.0.0.1 1234

Soubor se zakázaným inzerováním vzdálené třídy musí být přístupný. Za tímto účelem jej buď zkopírujeme do klienta a zahrneme do jeho CLASSPATH, nebo jej odstraníme z CLASSPATH serveru a zahrneme jeho cestu do serveru java.rmi.codebase (pokud není odstraněn z CLASSPATH serveru, volba java. rmi.codebase a klient nebude mít přístup k útržku). Pokud se podíváme do okna, kde běží RMI server, uvidíme, jak byl vzdálený objekt nalezen a jak byly provedeny jeho metody:

Viz také

Externí odkazy