A Java Remote Method Invocation API vagy Java RMI, egy Java programozói interfész, amely a Remote Procedure Call (RPC) objektumorientált megfelelője.
Az RMI kifejezés használata jelentheti csupán a programozási interfészt, de jelentheti egyúttal az API és JRMP kettősét is, amíg az RMI-IIOP jelentése, hogy az RMI a legtöbb funkcionalitást a támogató CORBA implementációra bízza.
Az eredeti RMI API programozói némileg általánosították a kódot, hogy támogassák a különböző implementációkat. Továbbá, az RMI interfész támogatásának érdekében a CORBA bővült az érték szerinti paraméterátadással. Ettől függetlenül az RMI-IIOP és JRMP implementációk még mindig nem rendelkeznek teljesen azonos interfésszel.
Az RMI funkciói a java.rmi csomagban, míg a legtöbb Sun implementáció a sun.rmi csomagban találhatóak. Fontos megjegyezni, hogy a Java 5.0 előtti verziókkal fejlesztőknek egy további fordítási lépésként a rmic parancsot is használniuk kell. Erre az 5.0 illetve ez feletti verziók esetén nincs szükség.
java.rmi
sun.rmi
rmic
A Jini egy sokkal korszerűbb verzióját szolgáltatja a Java RMI-nek. A működése ugyanaz, ellenben fejlettebb keresési képességeket és elosztott objektum alkalmazási mechanizmusokat nyújt.[1]
Az alábbi osztályok egy egyszerű RMI-t használó kliens-szerver programot implementálnak, ami megjelenít egy üzenetet.
RmiServer class—RMI kérésekre vár és implementálja az interfészt, amit a kliens a távoli metódusok hívására használ.
RmiServer
import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.RMISecurityManager; import java.rmi.server.UnicastRemoteObject; import java.rmi.registry.*; public class RmiServer extends UnicastRemoteObject implements RmiServerIntf { public static final String MESSAGE = "Hello world"; public RmiServer() throws RemoteException { } public String getMessage() { return MESSAGE; } public static void main(String args[]) { System.out.println("RMI server started"); // Egy security manager létrehozása és telepítése. if (System.getSecurityManager() == null) { System.setSecurityManager(new RMISecurityManager()); System.out.println("Security manager installed."); } else { System.out.println("Security manager already exists."); } try { //speciális kivétel kezelő registry készítéshez LocateRegistry.createRegistry(1099); System.out.println("java RMI registry created."); } catch (RemoteException e) { //do nothing, error means registry already exists System.out.println("java RMI registry already exists."); } try { //RmiServer példányosítása RmiServer obj = new RmiServer(); Naming.rebind("//localhost/RmiServer", obj); System.out.println("PeerServer bound in registry"); } catch (Exception e) { System.err.println("RMI server exception:" + e); e.printStackTrace(); } } }
RmiServerIntf class—Azon interfész definiálása, amit a kliens használ és a szerver implementál.
RmiServerIntf
import java.rmi.Remote; import java.rmi.RemoteException; public interface RmiServerIntf extends Remote { public String getMessage() throws RemoteException; }
RmiClient class—A kliens, ami megkapja a szerveren lévő távoli objektum referenciáját (proxy) és meghívja a metódusát, hogy megkapja az üzenetet. Ha a szerver objektum implementálta a java.io.Serializable interfészt a java.rmi.Remote helyett, szerializálva lesz, és értékként adódik át a kliensnek.[2]
RmiClient
import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.RMISecurityManager; public class RmiClient { // "obj" a távoli objektum referenciája RmiServerIntf obj = null; public String getMessage() { try { obj = (RmiServerIntf)Naming.lookup("//localhost/RmiServer"); return obj.getMessage(); } catch (Exception e) { System.err.println("RmiClient exception: " + e); e.printStackTrace(); return e.getMessage(); } } public static void main(String args[]) { // Egy security manager létrehozása és telepítése. if (System.getSecurityManager() == null) { System.setSecurityManager(new RMISecurityManager()); } RmiClient cli = new RmiClient(); System.out.println(cli.getMessage()); } }
A futtatás előtt készítenünk kell egy 'Stub' fájlt a használt interfészről az 'rmic' parancs segítségével.
rmic RmiServer
A fenti lépésre Java 5.0 verziótól nincs szükség.[3]
server.policy—Ez a fájl a szerveren szükséges a TCP/IP kommunikáció biztosítására.
server.policy
grant { permission java.net.SocketPermission "127.0.0.1:*", "connect,resolve"; permission java.net.SocketPermission "127.0.0.1:*", "accept"; };
A server.policy fájlt Java RTE D kapcsolójával ajánlott használni, pl.:
java.exe -Djava.security.policy=server.policy RmiServer
client.policy—Ez a fájl a kliens oldalon szükséges az RMI szerverhez való kapcsolódáshoz TCP/IP-vel.
client.policy
grant { permission java.net.SocketPermission "127.0.0.1:*", "connect,resolve"; };
no.policy—Ha mégis probléma merül fel a kapcsolódással, az alábbi fájlt érdemes kipróbálni a kliens vagy szerver oldalon.
no.policy
grant { permission java.security.AllPermission; };
Ez a szócikk részben vagy egészben a Java remote method invocation című angol Wikipédia-szócikk ezen változatának fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.