Il Client - Dipartimento di Informatica

Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Organizzazione della lezione
Lezione 14
Remote Method Invocation - 2
Vittorio Scarano
Corso di Programmazione Distribuita (2003-2004)
Laurea di I livello in Informatica
Università degli Studi di Salerno
• Un ripasso: +HOOR:RUOG
• Creazione di oggetti remoti che derivano da una
superclasse
• Istanziazione di un registry interno all’oggetto server
• Download dinamico di classi in RMI
2
Il diagramma di RemoteHello
Un esempio di uso: l'oggetto remoto Hello
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
• Definizione della Interface Remota
• definizione derivata da java.rmi.Remote
• ogni metodo deve lanciare java.rmi.RemoteException
• Scrivere la implementazione della Classe Server
•
•
•
•
•
•
specificare la interface remota
specificare il/i costruttore/i dell'oggetto remoto
implementare i metodi remoti
creare ed installare un security manager
creare una o più istanze di oggetti remoti
registrare gli oggetti al registry.
• Scrivere la Classe Client
• ottenere un riferimento remoto all'oggetto remoto dal registro
• invocare il/i metodo remoto
3
«interface»
«interface»
Remote
Remote
UnicastRemoteObject
UnicastRemoteObject
«interface»
«interface»
Hello
Hello
+ dimmiQualcosa(in daChi: String): String
+ dimmiQualcosa(in daChi: String): String
HelloClient
HelloClient
+ main(in args: String[]): void
+ main(in args: String[]): void
HelloImpl
HelloImpl
+ HelloImpl(): void
+ HelloImpl(): void
+ dimmiQualcosa(in daChi: String): String
+ dimmiQualcosa(in daChi: String): String
+ main(in args: String[]): void
+ main(in args: String[]): void
4
RMI: Il processo di creazione
1 - Definizione della interface remota
La interface remota dell'oggetto: il file Hello.java
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
• Interface
1
Definire la interface remota
Implementare la interface
Server
class
javac
rmic
Implementare
il client
Server
skeleton
Client
Stub
Lanciare rmiregistry
javac
Lanciare oggetti server
Lanciare
il client
Registrare oggetti server
Client
Server
Client
Stub
2
Server
class
Server
skeleton
Lanciare rmiregistry
javac
Lanciare oggetti server
Lanciare
il client
Client
Registrare oggetti server
Server
6
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
1
rmic
Implementare
il client
}
• Metodo
dimmiQualcosa
dichiarato
• Lancia
RemoteException
La implementazione dell'oggetto remoto:
il file HelloImpl.java (1)
Definire la interface remota
javac
String dimmiQualcosa(String daChi)
throws java.rmi.RemoteException;
– eredita da
java.rmi.Remote
5
RMI: Il processo di creazione
2 - Implementazione della interface remota
Implementare la interface
public interface Hello
extends java.rmi.Remote {
7
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class HelloImpl
extends UnicastRemoteObject
implements Hello {
public HelloImpl()
throws java.rmi.RemoteException {}
public String dimmiQualcosa(String daChi)
throws RemoteException {
System.out.println("Saluto "+daChi);
return "Ciao "+daChi+"!";
}
// continua……
• Derivato da …
• … e implementa la
interface remota
• Il costruttore (vuoto)
dell'oggetto remoto
– con chiamata
implicita al costruttore
della superclasse
• Implementazione del
metodo remoto
8
// continua … …
public static void main(String args[]) {
System.setSecurityManager(new
RMISecurityManager());
try {
HelloImpl obj = new HelloImpl();
Naming.rebind("HelloServer", obj);
System.out.println("Pronto!");
} catch (Exception e) {
e.printStackTrace();
}
} // end main
} // end classe HelloImpl
RMI: Il processo di creazione
3/4 - Compilazione con javac
• Crea ed installa un
security manager
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
La implementazione dell'oggetto remoto:
il file HelloImpl.java (2)
– utile per poter caricare
classi dinamicamente se
non sono presenti sul
CLASSPATH
• crea una istanza di
oggetto remoto obj
• registra l'oggetto sul
registry
1
Definire la interface remota
2
Implementare la interface
Implementare
il client
3
javac
4
rmic
Server
class
Server
skeleton
Client
Stub
Lanciare rmiregistry
javac
Lanciare oggetti server
Lanciare
il client
Registrare oggetti server
Client
9
Server
10
RMI: Il processo di creazione
5/6/7 - Lanciare rmiregistry e server
La compilazione del server HelloImpl
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
• Compilazione della interface:
– javac Hello.java
• Compilazione del server:
– javac HelloImpl.java
• Generazione stub e skeleton:
– rmic HelloImpl
che genera i file:
– HelloImpl_Stub.class
– HelloImpl_Skel.class
11
1
Definire la interface remota
2
Implementare la interface
3
javac
4
rmic
8
Client
Stub
Implementare
il client
javac
Lanciare
il client
Server
class
Server
skeleton
Lanciare rmiregistry
5
Lanciare oggetti server
6
Registrare oggetti server
7
9
10
Client
Server
12
Il Client: il file HelloClient.java
1
Definire la interface remota
2
Implementare la interface
3
javac
4
rmic
Server
class
Server
skeleton
8
Implementare
il client
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
RMI: Il processo di creazione
8 - Implementazione del Client
Client
Stub
Lanciare rmiregistry
5
Lanciare oggetti server
6
Registrare oggetti server
7
javac
Lanciare
il client
Client
Server
13
Client
Client
Objects
Objects
HelloClient
Stub Object
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Hello
Generate HelloImpl_Stub.class
da rmic
• Prende (se c’è) il primo
parametro come host e il
secondo come nome
• Ottiene un riferimento
remoto all'oggetto
remoto dal registro
• Hostname
• Invocare il metodo
remoto
14
RMI: Il processo di creazione
9- Compilazione del Client
Le classi generate nell’esempio
HelloClient
import java.rmi.*;
public class HelloClient {
public static void main(String args[]) {
String host = “localhost”;
String nome = “Pippo”;
if (args.length > 0 ) host = args[0];
if (args.length > 1 ) nome = args[1];
try {
Hello obj = (Hello)
Naming.lookup(
”rmi://”+host+”/HelloServer");
System.out.println("Ricevuto:"
+ obj.dimmiQualcosa(nome));
} catch (Exception e) {
e.printStackTrace();
}
}// fine main
}// fine classe HelloClient
Scritto
dal
programmatore
HelloImpl
HelloImpl_Skel.class
Skeleton Object
HelloImpl
HelloImpl
HelloImpl
15
1
Definire la interface remota
2
Implementare la interface
3
javac
4
rmic
8
Client
Stub
Implementare
il client
javac
Lanciare
il client
Server
class
Server
skeleton
Lanciare rmiregistry
5
Lanciare oggetti server
6
Registrare oggetti server
7
9
10
Client
Server
16
RMI: Il processo di creazione
10 - Lanciare il client
• Avendo a disposizione lo stub
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
La compilazione del client HelloClient
– HelloImpl_Stub.class
• Compilazione del client:
– javac HelloClient.java
Un ultimo passo: la security policy
– scrivendo un file che caratterizza i permessi dati a ciascuna
operazione
• Possibile scegliere politiche
– per tutte le macchine virtuali
– per singolo utente
– per applicazione
• Esempio: scrivere la policy più “liberale” (!) in un file
(chiamiamolo SROLF\DOO) nella directory corrente
19
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
3
javac
4
rmic
Server
skeleton
8
Client
Stub
Implementare
il client
javac
Lanciare
il client
Server
class
Lanciare rmiregistry
5
Lanciare oggetti server
6
Registrare oggetti server
7
9
10
Server
18
Esecuzione di Hello
• Necessario settare la security policy della JVM
grant {
permission java.security.AllPermission;
};
2
Implementare la interface
Client
17
1
Definire la interface remota
• Sulla macchina del server (serverhost):
– lanciare il registry sulla porta di default 1099
• rmiregistry &
• start rmiregistry
(Unix)
(Windows)
– lanciare il programma server con la policy:
• java -Djava.security.policy=policyall HelloImpl
• Sulla macchina del client:
– lanciare il programma client:
• java HelloClient serverhost Topolino
20
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Organizzazione della lezione
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
La sequenza delle azioni in UML
• Un ripasso: +HOOR:RUOG
• Creazione di oggetti remoti che derivano da una
superclasse
• Istanziazione di un registry interno all’oggetto server
• Download dinamico di classi in RMI
21
Come dichiarare un oggetto “remoto”
22
Un esempio: RemoteCounter
• Classe LocalCounter:
– ereditare da UnicastRemoteObject
– implementare la interfaccia dei servizi offerti
• Cosa accade se la nostra classe deve ereditare da
qualche altra classe?
• Si possono utilizzare dei metodi statici offerti da
UnicastRemoteObject per rendere l’oggetto utilizzabile
da remoto
– attraverso il metodo UnicastRemoteObject.exportObject()
– tipicamente, nel costruttore
– che deve lanciare una eccezione RemoteException
23
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
• Per poter usare RMI un oggetto server deve:
– classe “locale” con alcuni metodi e variabili di istanza
• Classe RemoteCounter:
– che eredita da LocalCounter e implementa la interface
Counter…
– dei cui metodi offre la implementazione
– aggiungendo anche alcuni metodi “locali”
• Classi di supporto
– CounterClient: per incrementare di un certo valore (fornito su
linea di comando) il contatore remoto
– CounterServer: per istanziare l’oggetto remoto
• offre anche una semplice shell di interrogazione
24
«interface»
Counter
La interface remote: Counter.java
LocalCounter
- value: int
+ getValue(): int
+ increment(): int
+ sum(in valore: int)
+ LocalCounter(in v: int)
+ localGetValue(): int
RemoteCounter
- name: String
CounterClient
+
+
+
+
+
+ main(in args: String[])
CounterServer
RemoteCounter(in n: String, in v: int)
getName(): String
getValue(): int
increment(): int
sum(in valore: int)
- ERRORMSG: String
+ main(in args: String[])
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Il diagramma di RemoteCount
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Counter extends Remote
{
int getValue()
throws RemoteException;
void sum(int valore)
throws RemoteException;
int increment()
throws RemoteException;
}
LocalCounter
+ LocalCounter(in v: int)
+ localGetValue(): int
RemoteCounter
- name: String
CounterClient
+ main(in args: String[])
+
+
+
+
+
– aggiunge il valore
indicato
26
La classe locale: LocalCounter.java
- value: int
+ getValue(): int
+ increment(): int
+ sum(in valore: int)
• sum()
– incrementa il
contatore di 1
RemoteCounter(in n: String, in v: int)
getName(): String
getValue(): int
increment(): int
sum(in valore: int)
CounterServer
- ERRORMSG: String
+ main(in args: String[])
27
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
«interface»
Counter
– preleva il valore
– eccezione remota
• increment()
25
Il diagramma di RemoteCount
• Tre metodi da
implementare per
l’accesso remoto
• getValue()
public class LocalCounter
{
public LocalCounter(int v) {
value = v;
}
public int localGetValue() {
return value;
}
// variabili di istanza
int value;
}
• Semplice esempio
• Costruttore
– inizializzazione
• Offre un metodo
(locale) per prelevare
il valore
• Variabile di istanza
28
«interface»
Counter
La classe locale: RemoteCounter.java (1)
LocalCounter
- value: int
+ getValue(): int
+ increment(): int
+ sum(in valore: int)
+ LocalCounter(in v: int)
+ localGetValue(): int
RemoteCounter
- name: String
CounterClient
+ main(in args: String[])
+
+
+
+
+
CounterServer
RemoteCounter(in n: String, in v: int)
getName(): String
getValue(): int
increment(): int
sum(in valore: int)
- ERRORMSG: String
+ main(in args: String[])
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Il diagramma di RemoteCount
import java.rmi.*;
import java.rmi.server.*;
public class RemoteCounter
extends LocalCounter
implements Counter {
public RemoteCounter(String n, int v)
throws RemoteException {
super (v);
name = n;
UnicastRemoteObject.exportObject(this);
try {
Naming.rebind(name,this);
} catch (Exception e)
{System.out.println ("Eccezione:"+e);}
}
// continua….
• Estende la classe
locale e implementa
la interface
• Costruttore
– costruttore
superclasse
– inizializzazione
– esportazione oggetto
remoto
– rebind
29
Il diagramma di RemoteCount
La classe locale: RemoteCounter.java (2)
}
• Metodi remoti
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
// continua…
public int getValue()
throws RemoteException {
return value; }
public void sum (int valore)
throws RemoteException {
value += valore; }
public int increment()
throws RemoteException {
sum (1);
return value;
}
public String getName() {
return name;
}
String name;
30
– getValue()
– sum()
– increment()
• Metode locale
– getName()
• Variabile istanza
31
«interface»
Counter
LocalCounter
- value: int
+ getValue(): int
+ increment(): int
+ sum(in valore: int)
+ LocalCounter(in v: int)
+ localGetValue(): int
RemoteCounter
- name: String
CounterClient
+ main(in args: String[])
+
+
+
+
+
RemoteCounter(in n: String, in v: int)
getName(): String
getValue(): int
increment(): int
sum(in valore: int)
CounterServer
- ERRORMSG: String
+ main(in args: String[])
32
import java.util.*;
import java.io.*;
import java.rmi.*;
import java.rmi.server.*;
public class CounterServer {
public static void main (String args[]) {
BufferedReader in=null;
String cmd;
if (System.getSecurityManager() == null)
System.setSecurityManager(new
RMISecurityManager());
try {
RemoteCounter cont = new
RemoteCounter ("Contatore",0);
System.out.println ("Pronto!");
in = new BufferedReader(new
InputStreamReader(System.in));
// continua…
La classe server: CounterServer.java (2)
• Offre una shell di
comandi “locali”
• Solo il metodo main()
• Installazione SM
• Creazione oggetto
remoto
• Apertura Stream per
input
33
«interface»
Counter
- value: int
+ LocalCounter(in v: int)
+ localGetValue(): int
RemoteCounter
- name: String
CounterClient
+ main(in args: String[])
+
+
+
+
+
RemoteCounter(in n: String, in v: int)
getName(): String
getValue(): int
increment(): int
sum(in valore: int)
– locali ereditati da
LocalCounter:
localGetValue()
– locali: getName()
– remoti: increment()
• Costante per
messaggio di errore
34
La classe client: CounterClient.java
LocalCounter
+ getValue(): int
+ increment(): int
+ sum(in valore: int)
• Lettura comando
• Esecuzione metodi
}
CounterServer
- ERRORMSG: String
+ main(in args: String[])
35
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Il diagramma di RemoteCount
while (true) {
System.out.print("Comandi >");
cmd = in.readLine();
if (cmd.equals ("close"))
System.exit(0);
else if (cmd.equals ("localGetValue"))
System.out.println (
cont.localGetValue());
else if (cmd.equals ("getName"))
System.out.println (
cont.getName());
else if (cmd.equals("increment"))
System.out.println (cont.increment());
else System.out.println (ERRORMSG);
} // end while
} catch (Exception e)
{ System.out.println("Ecc."+e);}
}
static final String ERRORMSG = "Uhh?";
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
La classe server: CounterServer.java (1)
import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.*;
public class CounterClient {
public static void main (String args[ ]) {
String host = "localhost";
if (System.getSecurityManager() == null)
System.setSecurityManager(new
RMISecurityManager());
if (args.length == 2) host = args[1];
try {
Counter cont = (Counter)
Naming.lookup("rmi://"+host+"/Contatore");
int limite=Integer.parseInt(args[0]);
for (int i=0; i<limite; i++) cont.increment();
System.out.println ("Tot="+cont.getValue());
} catch (Exception e)
{ System.out.println("Eccezione"+e);}
}
}
• Chiama l’incremento
args[0] volte
• Installazione SM
• Riferimento remoto
• Chiamata di
increment()
• Chiamata di
getValue()
36
Istanziazione di un registry dall’interno
• Un ripasso: +HOOR:RUOG
• Creazione di oggetti remoti che derivano da una
superclasse
• Istanziazione di un registry interno all’oggetto server
• Download dinamico di classi in RMI
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Organizzazione della lezione
• E’ possibile istanziare un registry dall’interno di un
programma
– utile per evitare la partenza del servizio di naming da shell
– indispensabile (come vedremo) per usare socket particolari
• Facciamo un esempio:
– esempio Hello (lezione precedente)
– unica modifica necessaria sul server HelloImpl
• che deve creare un oggetto di tipo registry
• ottenerne il riferimento
• per poter fare il bind dell’oggetto
37
Il diagramma di RemoteHello
38
La interface remota dell'oggetto: il file Hello.java
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
package hello;
39
public interface Hello
extends java.rmi.Remote {
String dimmiQualcosa(String daChi)
throws java.rmi.RemoteException;
}
• Dichiarazione di
package
• Interface
– eredita da
java.rmi.Remote
• Metodo
dimmiQualcosa
dichiarato
• Lancia
RemoteException
40
public HelloImpl()
throws java.rmi.RemoteException {}
public String dimmiQualcosa(String daChi)
throws RemoteException {
System.out.println("Saluto "+daChi);
return "Ciao "+daChi+"!";
}
// continua……
• Identico alla
precedente tranne:
– import di registry
• Il costruttore (vuoto)
dell'oggetto remoto
– con chiamata
implicita al costruttore
della superclasse
• Implementazione del
metodo remoto
41
Esecuzione di Hello
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
package hello;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.registry.*;
public class HelloImpl
extends UnicastRemoteObject
implements Hello {
La implementazione dell'oggetto remoto:
il file HelloImpl.java (2)
// continua … …
public static void main(String args[]) {
System.setSecurityManager(new
RMISecurityManager());
try {
HelloImpl obj = new HelloImpl();
LocateRegistry.createRegistry(1099);
Registry registry =
LocateRegistry.getRegistry(1099);
registry.rebind("HelloServer", obj);
System.out.println("Pronto!");
} catch (Exception e) {
e.printStackTrace();
}
} // end main
} // end classe HelloImpl
• Crea ed installa un
security manager
– utile per poter caricare
classi dinamicamente se
non sono presenti sul
CLASSPATH
• crea una istanza di
oggetto remoto obj
• Differenza:
– crea un registry su porta
1099
– ottiene un riferimento
– fa il rebind()
– era semplicemente
Naming.rebind("HelloServer", obj);
42
Organizzazione della lezione
• Sulla macchina del server (serverhost):
– non necessario lanciare il registry sulla porta di default 1099
– lanciare il programma server con la policy:
• java -Djava.security.policy=policyall hello.HelloImpl
• Sulla macchina del client:
– lanciare il programma client:
• java hello.HelloClient serverhost Topolino
43
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
La implementazione dell'oggetto remoto:
il file HelloImpl.java (1)
• Un ripasso: +HOOR:RUOG
• Creazione di oggetti remoti che derivano da una
superclasse
• Istanziazione di un registry interno all’oggetto server
• Download dinamico di classi in RMI
44
• Tra le capacità “particolari” di Java
– quella di permettere il caricamento a run-time delle classi
necessarie, dovunque esse si trovino (su host locale oppure
tramite una URL
• Tipicamente:
– un ClassLoader per la JVM deve conoscere le possibili
locazioni delle classi da caricare
• Codebase
– una sorgente di “classi” da cui caricare
– tipicamente, in locale, settato al CLASSPATH (variabile di
ambiente)
45
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Caricamento dinamico delle classi
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Codebase e RMI
• In generale, è necessario indicare
– alle classi client come poter accedere (anche remotamente)
alla classe stub dell’oggetto server di cui vuole usare i
servizi (metodi)
• In generale:
– possibile indicare una URL che specifichi dove si trova la
classe indicata
– usato di solito con un server HTTP o FTP che svolga questo
compito
• Uso del codebase:
– java -Djava.rmi.server.codebase=http://www.xyz.com/ class
46
Lo scenario 1: la sequenza di azioni (1)
Due scenari diversi
• 1. il server deve poter indicare al client dove si trova lo
stub che si incaricherà delle comunicazioni con sé
stesso
• 2. il client effettua una chiamata remota ad un metodo
passando un oggetto la cui classe è sconosciuta al
server (ma ovviamente è sottoclasse della classe del
parametro del metodo del server)
47
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Download dinamico di classi
RMI
client
RMI
registry
1. bind server
RMI
server
Locazione URL
http://s_host
java -Djava.rmi.server.codebase=http//s_host
server
48
RMI
client
RMI
registry
Lo scenario 1: la sequenza di azioni (3)
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Lo scenario 1: la sequenza di azioni (2)
1. bind server
RMI
server
Locazione URL
http://s_host
il registry annota la definizione della
URL per la classe e carica la definizione
della classe
RMI
client
2. Naming.lookup
3. reference
remota (con
il codebase)
RMI
registry
1. bind server
RMI
server
Locazione URL
http://s_host
49
RMI
client
5. stub
restituito
2. Naming.lookup
3. reference
remota (con
il codebase)
RMI
registry
4. richiesta
stub
Lo scenario 1: la sequenza di azioni (5)
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Lo scenario 1: la sequenza di azioni (4)
50
1. bind server
RMI
server
Locazione URL
http://s_host
51
RMI
client
5. stub
restituito
2. Naming.lookup
3. reference
remota (con
il codebase)
4. richiesta
stub
RMI
registry
6. chiamata
remota
1. bind server
RMI
server
Locazione URL
http://s_host
52
I parametri passati a metodi remoti
Due scenari diversi
• 1. il server deve poter indicare al client dove si trova lo
stub che si incaricherà delle comunicazioni con sé
stesso
• 2. il client effettua una chiamata remota ad un metodo
passando un oggetto la cui classe è sconosciuta al
server (ma ovviamente è sottoclasse della classe del
parametro del metodo del server)
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Caricamento dinamico delle classi
• Tre possibilità
– tipi di dati primitivi
• il server conosce come interpretarli
– oggetti la cui classe si trova nel CLASSPATH del server
• il server conosce come interpretarli
– oggetti la cui classe non si trova nel CLASSPATH del
server
• il parametro era per un oggetto della classe A, ma viene passato un
oggetto della classe B, sottoclasse di A, che risulta sconosciuta dal
server
• necessario che il server la possa reperire
53
Lo scenario 2: la sequenza di azioni (1)
54
Lo scenario 2: la sequenza di azioni (2)
RMI
client
chiamata remota in
cui l’argomento è una
sottoclasse non nota al
server
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
Programmazione Distribuita (2003-2004). Vi.ttorio Scarano
java -Djava.rmi.server.codebase=http//c_host client
RMI
server
il client ha la definizione
della sottoclasse su un server
Locazione URL
http://c_host
55
RMI
client
chiamata remota in
cui l’argomento è una
sottoclasse non nota al
server
il client ha la definizione
della sottoclasse su un server
RMI
server
il server accede alla
definizione della sottoclasse
Locazione URL
http://c_host
56