Vyvolání vzdálené metody Java
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
- Jednoduchý příklad RMI
- Výukový program Java RMI Výukový program od Sun Microsystems (v angličtině)
- Trail: RMI Java Oficiální dokumentace RMI
- Přehled RMI aplikací Oficiální úvod do Java RMI aplikací