Java Remote Method Invocation
Programmazione in Rete e Laboratorio
Matteo Baldoni Dipartimento di Informatica Universita` degli Studi di Torino C.so Svizzera, 185 I-10149 Torino baldoni@di.unito.it
http://www.di.unito.it/~baldoni/didattica
2
Comunicazione distribuita
Invocazione di metodi sull’oggetto remoto
Java VM1 Port1
Java VM2 Port 2
3
RMI: goal
■
Rendere trasparente l’invocazione remota di metodi su oggetti Java che risiedono su diverse Virtual machines (evoluzione di Remote Procedure Call, RPC)
■
offrire un modello distribuito che preservi maggiormente la semantica degli oggetti Java
■
rendere il piu’ semplice possibile la scrittura di applicazioni distribuite
■
RMI è un ORB (Object Request Broker) ma non un CORBA (Common Object Request Broker Architecture) come stabilito dall’OMG (Object Management Group)
■
analogo a DCOM della Microsoft
4 Livello di Trasporto Rete Livello di Trasporto Livello di riferimento
remoto
Livello di riferimento remoto Livello stub Livello stub
Applicazione Server
Architettura RMI
Applicazione Client
Skeleton per le versioni precedenti a Java 1.2 Supporta vari
protocolli di invocazione:
unicast, multicast
Si occupa della effettiva connessione, della identificazione degli oggetti remoti, del mezzo, TCP/IP, UDP (nota: RMI usa per ora solo TCP/IP)
Ogni livello è indipen- dente dall’altro!
Si occupa di preparare (marshalling) la remote call e gli oggetti per la trasmissione
5
Architettura RMI
■
Il sistema RMI e` costituito da tre livelli per supportare flessibilità nella comunicazione
■
Ogni livello ha le sue interfacce di comunicazione con relativi protocolli
◆
stub (e skeleton) layer: canale di comunicazione tra clients e server
◆
remote reference layer: supporto di diversi protocolli di invocazione tipo Unicast e Multicast
◆
transport layer: supporta la comunicazione a basso livello, tipo TCP/IP
6
RMI
Simile all’invocazione di metodi locali
■
i parametri dei metodi possono essere oggetti
■
il polimorfismo e` supportato: oggetti diversi possono rispondere a stessi messaggi
ma
■
i client interagiscono con interfacce di oggetti (stub) non con la loro implementazione (che sta nella VM remota)
■
parametri passati per copia, non per referenza (passaggio per referenza solo dentro a una VM)
■
Distributed Garbage Collector (DGC)
7
RMI in pratica
■
L’oggetto blu sulla JVM Client desidera inviare un messaggio all’oggetto rosso sulla JVM Server, gli oggetti giallo e azzurro fanno parte dei parametri del messaggio
■
L’oggetto rosso sulla JVM Server terminata l’esecuzione restituisce l’oggetto verde come valore di ritorno oppure solleva un’eccezione
IP Address IP Address
Server Client
JVM JVM
messaggio valore di ritorno o eccezione
8
RMI in pratica: Interfaccia
■
Il client deve disporre di un’interfaccia che descriva l’oggetto remoto
■
È necessario che l’interfaccia estenda java.rmi.Remote
■
Ogni metodo descritto puo` lanciare un’eccezione di tipo java.rmi.RemoteException
public interface Distributor extends java.rmi.Remote { Job getNewJob() throws java.rmi.RemoteException;
Job getNewJob(Message msg) throws java.rmi.RemoteException;
}
9
RMI in pratica: Implementazione
■
Il Server implementa la classe che esegue praticamente i metodi che sono descritti nell’interfaccia remota
■
Questa classe è necessario che estenda la classe
java.rmi.server.UnicastRemoteObject (attualemente l’unica disponibile, multicast in una futura versione) che rende accessibile le sue istanze remotamente (puo` creare uno stub per la classe)
public class DistributorImpl
extends java.rmi.server.UnicastRemoteObject implements Distributor {
[..]
public Job getNewJob() throws java.rmi.RemoteException { […]
} […]
} 10
RMI in pratica: rmiregistry, bind (rebind)
■
Gli oggetti remoti sono individuati tramite un IP, un numero di porta e un
nome (una stringa)■ server registry: processo “pagine
gialle”
IP Address IP Address
Server Client
JVM JVM
registry
<IP, port, name>
<IP, port, name>
stub Naming.rebind
Non è necessario registrare l’oggetto verde
Lo stub è necessario durante il bind Si registra
l’oggetto rosso presso il servizio di pagine gialle
Reference Layer:
apertura di un server socket
11
RMI in pratica: rmiregistry, bind (rebind)
■
La classe Naming appartiene al package java.rmi
■
rmiregistry puo` anche essere attivato indipendentemente dal server tramite il comando “rmiregistry 2000”
public DistributorImpl() throws RemoteException { […]
try {
java.rmi.registry.LocateRegistry.createRegistry(2000);
Naming.rebind("rmi://130.192.239.145:2000/distributor",this);
}
catch (Exception e) {
System.err.println("Failed to bind to RMI Registry");
System.exit(1);
} }
porta
IP address nome oggetto
remoto
12
RMI in pratica: rmiregistry, lookup
IP Address IP Address
Server Client
JVM JVM
registry
<IP, port, name>
<IP, port, name>
stub stub
Naming.lookup
■
Il client ottiene uno stub (surrogato dell’oggetto rosso presso il client) tramite il server registry
■
Deve conoscerne IP, porta e nome
13
RMI in pratica: rmiregistry, lookup
■
L’oggetto remoto è contattato tramite il server registry
■
È necessario conoscerne l’indirizzo IP, il numero della porta e il nome con cui è registrato
public class Client { Distributor server;
[…]
public Client() { try {
server = (Distributor)Naming.lookup(
"rmi://130.192.239.145:2000/distributor”);
}
catch(Exception e) {
System.out.println("Failed to find distributor" + e.getMessage());
} }
Tipo definito dall’interfaccia!
14
RMI in pratica: stub client
IP Address IP Address
Server Client
JVM JVM
registry
<IP, port, name>
stub stub messaggio
■
L’oggetto blu invia un messaggio al surrogato oggetto rosso presso lo stub client
■
Lo stub client inizializza la chiamata remota ed organizza i parametri da inviare
L’oggetto giallo e azzurro vengono serializzati e organizzati per la spedizione (marshalling)
Garbage collector:
mantiene un riferimento all’oggetto rosso: non puo` essere eliminato
15
RMI in pratica: invio messaggio
■
L’oggetto remoto è ora utilizzabile come un qualsiasi oggetto locale
■
lo stub ne è un surrogato
public class Client { [..]
public void process() { try {
Job myJob = server.getNewJob(new Message("Richiesta Job!"));
myJob.process();
}
catch (Exception e) {
System.out.println("Failed to receive job " + e.getMessage());
} } [..]
}
16
RMI in pratica: connessione
IP Address IP Address
Server Client
JVM JVM
stub stub
TCP/IP
■
Il livello di trasporto è responsabile per una connessione, nel server ascolta le richieste in arrivo
■
mantiene la tabella degli oggetti remoti nel particolare address space
■
Scambia le informazioni con il reference layer
registry
<IP, port, name>
Il livello di trasporto apre un socket per la connessione
Connessione temporanea!
Anche HTTP se c’è un firewall
17
RMI in pratica: stub server
IP Address IP Address
Server Client
JVM JVM
stub stub
TCP/IP
registry
<IP, port, name>
■
Lo stub server riorganizza i parametri (unmarshalling)
■
individua l’oggetto da chiamare attivando il metodo desiderato (informazione contenuta nel pacchetto ricevuto)
Attenzione non vi è nessun riferimento agli oggetti giallo e azzurro sul client passati come parametro:
sono copie!
18
RMI in pratica: la risposta
IP Address IP Address
Server Client
JVM JVM
stub stub
Invia valore di ritorno o eccezione
TCP/IP
■
Lo stub del server cattura e riorganizza il valore restituito dall’evecuzione del metodo sull’oggetto rosso
■
Lo stub server invia allo stub del client un pacchetto contenente le informazioni raccolte (l’oggetto verde)
registry
<IP, port, name>
19
RMI in pratica: la risposta
■
Il server esegue il metodo invocato ed invia il valore di ritorno come se la chiamata fosse locale
public DistributorImpl() throws RemoteException { […]
public Job getNewJob(Message msg) { System.out.println(msg);
if( count < jobs.size()) {
return (Job)jobs.elementAt(count++);
} else { System.exit(0);
} return null;
} […]
} 20
RMI in pratica: ricezione
IP Address IP Address
Server Client
JVM JVM
stub stub
TCP/IP
registry
<IP, port, name>
■
Lo stub client riorganizza le informazioni ricevute o l’eccezione sollevata
■
La connessione viene quindi disattivata
21
RMI in pratica: ricezione
■
Il valore di ritorno è utilizzato come se fosse ora un oggetto locale ma non ha nessun riferimento con quello creato sul server (come per i parametri inviati con la chiamata)
public class Client { [..]
public void process() { try {
Job myJob = server.getNewJob(new Message("Richiesta Job!"));
myJob.process();
}
catch (Exception e) {
System.out.println("Failed to receive job " + e.getMessage());
} } [..]
}
22
RMI: riassunto
■
Nell’esempio che vedremo:
◆
javac *.java
◆
rmic -v1.2 DistributorImpl
◆
rmiregistry 2000 &
◆
java DistributorImpl
◆
java Client
Senza l’opzione viene creato anche il file DistributorImpl_Skel.class compatibile sia con Java 1.1 e 1.2 Crea il file:
DistributorImpl_Stub.class
Attiva il server registry Attiva il server
Esegue il client Dopo in bind è attivo un thread separato per gestire le richieste di
connessione, termina con CTRL-C
23
RMI: download dello stub
IP Address IP Address
Server Client
JVM JVM
registry
<IP, port, name>
<IP, port, name>
stub stub
TCP/IP
Web Server
HTTPdownload
Security Manager file di criteri
■
Lo stub generato dal server deve essere disponibile al client ma questo, in genere, è remoto…
■
Puo` essere scaricato tramite HTTP
24
java.rmi.server.codebase property
■
La proprieta` codebase indica dove cercare una classe remotamente
■
È l’analogo del CLASSPATH
■
Protocolli: file, ftp, o http
IP Address IP Address
Server Client
JVM JVM
registry
<IP, port, name>
<IP, port, name>
stub Naming.rebind
Il server viene avviato specificando la proprieta` codebase
java -Djava.rmi.server.codebase=http://Host/dirctory/
Web Server L’informazione del
codebase è memorizzata nel registry
25
RMI: security manager
■
RMISecurityManager con l’associato file di criteri permette di scaricare mediante il protocollo HTTP
■
È necessario un file di criteri
public class Client { Distributor server;
[…]
public Client() { try {
System.setSecurityManager(new RMISecurityManager());
server = (Distributor)Naming.lookup(
"rmi://130.192.239.145:2000/distributor”);
}
catch(Exception e) {
System.out.println("Failed to find distributor" + e.getMessage());
}
} 26
RMI: security manager
■
Per utilizzare il file di criteri nel client:
◆
java -Djava.security.policy=client.policy
■
Per indicare da dove scaricare il file stub dal server:
◆
java -
Djava.rmi.server.codebase=http://baldo.di.unito.it/~baldoni/dowload/
rmi1/ DistributorImpl
grant {
permission java.net.SocketPermission "130.192.239.145:1024-65535", "connect";
permission java.net.SocketPermission "130.192.239.1:80", "connect";
};
file client.policy
27
RMI: polimorfismo
IP Address IP Address
Server Client
JVM JVM
registry
<IP, port, name>
<IP, port, name>
stub stub
TCP/IP
Web Server
HTTP download
Security Manager file di criteri
■
L’oggetto inviati tramite RMI preservano il loro vero tipo
■
Ma se il valore restituito è piu`
specializzato di quello atteso dal client che succede?
■
Download delle classi per trattare l’oggetto specializzato!
28
RMI: polimorfismo
■
E se l’oggetto inviato è piu` specializzato di quello atteso dal server?
■
Download delle classi via HTTP durante l’esecuzione del metodo sull’oggetto remoto (sul server)
■
IL server necessita a sua volta di un Security Manager per il controllo delle classi scaricate
■
È nececessario un file di criteri per il download anche per il server
■
Il client deve specificare dove scaricare le classi
29
RMI: polimorfismo
IP Address IP Address
Server Client
JVM JVM
registry
<IP, port, name>
<IP, port, name>
stub stub
TCP/IP Web Server
Web Server HTTP
download HTTPdownload
Security Manager file di criteri file di criteri
30
Bibliografia
■
C. S. Horstmann, G. Cornell. Java 2 Tecniche Avanzate, McGrawHill, 2000. ISBN 88-386-4071-8. Capitolo 5.
■