Remote Method Invocation
I sistemi distribuiti richiedono che processi eseguiti su differenti host siano in grado di comunicare fra loro.Per le comunicazioni più semplici Java offre il meccanismo delle socket che richiedono l’implementazione di un protocollo mediante il quale client e server si scambiano messaggi.
Un’alternativa è rappresentata dalle Remote Procedural Call (RPC): lo sviluppatore ha l’illusione di chiamare una procedura locale delegando al sistema il compito di trasformare la richiesta in un’invocazione di una procedura residente su un altro host.
Le Remote Procedural Call tuttavia non si prestano molto all’implementazione di applicazioni distribuite object-oriented nelle quali non vi è la sola invocazione di procedure remote ma la "condivisione" di veri e propri oggetti.
Sistemi di questo tipo richiedono quindi un meccanismo per l’invocazione di metodi remoti (Remote Method Invocation) in cui un riferimento locale (stub) provvede a gestire l’invocazione dei metodi di un oggetto remoto.
Le applicazioni RMI sono generalmente costituite da due parti:
- la parte server crea gli oggetti remoti ed i riferimenti a questi e quindi attende l’invocazione dei metodi da parte di un client
- la parte client recupera i riferimenti a questi oggetti e ne invoca i metodi
- poter recuperare oggetti remoti
- comunicare con oggetti remoti
- caricare classi per oggetti che sono passati come parametri o restituiti come valore
Per recuperare oggetti remoti esistono due approcci: registrarli (rmiregistry) oppure passare e ricevere i riferimenti a questi come parte di una normale operazione.

Remote Method Invocation
L’invocazione di metodi remoti è totalmente trasparente al programmatore: i livelli Remote Reference Layer e Transport Layer si occupano di fatto della gestione a basso livello della comunicazione:
- Il Remote Reference Layer (RRL) ha il compito di instaurare la connessione fra il client e il server eseguendo operazioni di codifica e decodifica dei dati
- Il Transport Layer esegue la connessione vera e propria tra le macchine utilizzando quindi i socket con il protocollo TCP/IP
In definitiva quindi con RMI tutte le parti di una applicazione distribuita possono agire sia come client che come server.
Oggetti remoti
In Java un oggetto remoto è un oggetto i cui metodi possono essere invocati da remoto ed è descritto da una o più interfacce: RMI di fatto consiste nell’invocazione dei metodi di un’interfaccia remota su un oggetto remoto.Un’interfaccia remota deve soddisfare i seguenti requisiti:
- estendere l’interfaccia java.rmi.Remote
- dichiarare metodi che includano le eccezioni nella clausola throws e che definiscano gli oggetti remoti passati come parametri o restituiti come risultato mediante interfacce remote.
public interface MiaInterfaccia extends java.rmi.Remote { String getRisposta(String risposta) throws java.rmi.RemoteException; }E’ opportuno precisare che a differenza delle chiamate locali le chiamate remote possono anche fallire a causa di:
- problemi di comunicazione
- errori nel passaggio di parametri o nel recupero di valori
- errori di protocollo
L’implementazione del comportamento di un oggetto avviene estendendo la classe UnicastRemoteObject la quale può implementare più interfacce remote e può anche contenere metodi non definiti nelle interfacce interfacce stesse con la limitazione che tali metodi non potranno essere invocati da remoto.
public class OggettoRemoto extends java.rmi.server.UnicastRemoteObject implements MiaInterfaccia { public String getRisposta(String risposta) throws java.rmi.RemoteException { return risposta; } }Gli argomenti passati ed i valori ritornati devono necessariamente essere degli oggetti serializzabili ovvero dei tipi primitivi o che comunque implementino l’interfaccia java.io.Serializable.
Quando parametri o valore di ritorno devono essere convertiti in oggetti nella JVM che li riceve occorre disporre di tutte le definizioni delle corrispondenti classi.
In particolare per ogni classe il metodo annotateClass aggiunge allo stream il risultato dell’invocazione del metodo java.rmi.server.RMIClassLoader.getClassAnnotation il quale può essere null o una stringa rappresentativa di un URL al quale può essere recuperata la definizione della classe stessa.
Il metodo resolveClass invece restituisce il risultato dell’invocazione del metodo RMIClassLoader.loadClass con il nome della classe desiderata come unico parametro.
Stub e Skeleton
Uno Stub è una rappresentazione locale di un oggetto: il client invoca cioè i metodi dello Stub il cui compito sarà quello di invocare i metodi dell’oggetto remoto che rappresenta.Quando viene invocato un metodo lo Stub questo provvede a compiere le seguenti operazioni:
- inizia una connessione con la Java Virtual Machine che contiene l’oggetto remoto
- trasmette i parametri alla JVM
- aspetta il risultato dell’invocazione del metodo
- legge il risultato o l’eccezione generata
- restituisce il risultato a chi ha invocato il metodo
- leggere i parametri di un’invocazione remota
- invocare il metodo remoto dell’oggetto che rappresenta
- restituire il risultato al chiamante

Comunicazione
Il diagramma mette in evidenza le varie fasi della comunicazione fra Stub e Skeleton quando viene invocato un metodo di un oggetto remoto.Per semplicità non vengono illustrati il Remote Reference Layer ed il Transport Layer responsabili dell’invio e della codifica delle informazioni scambiate fra Stub e Skeleton.
rmic [-vcompat] oggettoremotoche genera:
oggettoremoto_Stub.class e oggettoremoto_Skel.class
Registrazione di un oggetto
Per usufruire di un servizio il client deve essere in grado di localizzare il server che fornisce il servizio stesso.Esistono tre approcci al problema:
- Il client conosce l’indirizzo del server
- L’utente dice all’applicazione client dov’è il server
- Un servizio standard (naming service) noto al client è in grado di fornire informazioni relative alla locazione di determinati servizi.
Mentre è possibile creare associazioni solo sull’ RMIRegistry locale la ricerca degli oggetti può avvenire su qualunque host.
- AlreadyBoundException se il nome logico è gia utilizzato
- MalformedURLException per errori nella sintassi dell’URL dell’oggetto remoto
- RemoteException negli altri casi
... OggettoRemoto oggettoremoto = new OggettoRemoto(); Naming.rebind("//localhost/OggettoRemoto ",oggettoremoto); ...Una volta che il Server ha registrato l’oggetto, il Client può recuperare un riferimento a questo (lo stub) mediante il metodo Naming.lookup(String name) dove name è nella forma //host:port/nomeoggettoremoto
MiaInterfaccia oggetto= (MiaInterfaccia)Naming.lookup("//localhost/OggettoRemoto");e quindi richiamare i metodi dell’oggetto:
String risposta = oggetto.getRisposta("risposta");Naturalmente la classe Naming offre anche metodi per:
- eliminare la registrazione di un oggetto unbind(String name)
- ottenere una lista degli oggetti registrati list(String name)
- sovrascrivere una registrazione rebind(String name, Remote obj)
Sicurezza e Codebase
Per rendere maggiormente sicure le applicazioni RMI è possibile impedire che le classi scaricate dal Server ed eseguite sul Client effettuino operazioni per le quali non sono state preventivamente abilitate.Per questa ragione una delle prime operazioni che Client e Server dovrebbero effettuare prima di invocare metodi remoti o registrare oggetti remoti è quella di installare sul sistema un Security Manager il quale preleva i permessi da un file policy specificato al momento del lancio delle applicazioni.
if(System.getSecurityManager() == null) { System.setSecurityManager(new RMISecurityManager()); }
java -Djava.security.policy = echo.policy Server java -Djava.security.policy = echo.policy ClientAffinchè Client e Server possano disporre delle definizioni delle classi necessarie all’interazione è possibile specificare il codebase al quale reperirle.
Il codebase può essere:
- una directory del filesystem locale (file://)
- l’indirizzo di un server FTP (ftp://)
- l’indirizzo di un server http (http://)
java -Djava.rmi.server.codebase= "http://server_host_name/... MioClient" java -Djava.rmi.server.codebase= "http://client_host_name/... MioServer"
Remote Method Invocation Home
Pagina dedicata all'invocazione di metodi remoti sul sito SUN
Pagina dedicata all'invocazione di metodi remoti sul sito SUN
jGuru: Remote Method Invocation (RMI)
Tutorial sull'invocazione dei metodi remoti
Tutorial sull'invocazione dei metodi remoti