Vous êtes sur la page 1sur 44

<< De la méthode, toujours

…>>

RMI, les bases

Cours "Réseaux et systèmes répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 1
Définitions
RMI = Remote Method Invocation
RMI est une solution pure Java permettant de réaliser l’invocation à
distance de méthode d’objet
Elle est accessible à travers les classes et interfaces prédéfinies d’API
Java
Ces API sont :
java.rmi
java.rmi.server
java.rmi.registry
Ainsi, les composants de l’orb RMI sont :
Les API
Le compilateur IDL
L’annuaire ou adaptateur

Les descriptions des API qui suivent sont volontairement incomplètes afin de décrire l’essentiel.

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 2
Les API : java.rmi.*
class Naming
Cette classe gère le service de nommage
static void bind(String name, Remote obj)
Binds the specified name to a remote object.
static String[] list(String name)
Returns an array of the names bound in the registry.
static Remote lookup(String name)
Returns a reference, a stub, for the remote object associated with the
specified name.
static void rebind(String name, Remote obj)
Rebinds the specified name to a new remote object.
static void unbind(String name)
Destroys the binding for the specified name that is associated with a
remote object.
class RMISecurityManager
Cette classe gère les autorisations d'utilisation de Java pour RMI
System.setSecurityManager(new RMISecurityManager());
Interface Remote
Utilisé dans les interfaces (IDL)

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 3
Exemple de RMISecurityManager
Les RMIs propose un gestionnaire de sécurité RMISecurityManager qui
par défaut interdit tout ce qu'un SecurityManager peut interdire, sauf la
définition de classe.
classe Pour permettre plus de chose il faut écrire son propre
gestionnaire de sécurité héritant de RMISecurityManager .
Exemple d'un serveur de calcul de complexe ou toutes les classes sont
chargées dynamiquement par le client.
package test.rmi;
import java.rmi.*;
import java.util.*;
public class ComplexCompute {
public static void main(String [] args) throws Exception {
Properties p=System.getProperties();
p.put("java.rmi.server.codebase","http://xxxx.fr/compte/CLASSES");
System.setProperties(p);
System.setSecurityManager(new RMISecurityManager());
ComplexOps obj = (ComplexOps) Naming.lookup("//"+ args[0]+
":10003/ComplexOps");
Complex c1 = obj.newComplex(1,1);
Complex c2 = obj.newComplex(2,2);
Complex c3 = obj.addComplex(c1,c2);
Complex c4 = obj.multComplex(c1,c2);
System.out.println(c1 + " + " + c2 + " = " + c3);
System.out.println(c1 + " * " + c2 + " = " + c4);
} }

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 4
Les API : java.rmi.server.*
class UnicastRemoteObject
Cette classe gère tout ce qui concerne un "servant" pour RMI
protected UnicastRemoteObject()
Creates and exports a new UnicastRemoteObject object using an anonymous port.
protected UnicastRemoteObject(int port)
Creates and exports a new UnicastRemoteObject object using the particular
supplied port.
protected UnicastRemoteObject(int port, RMIClientSocketFactory csf,
RMIServerSocketFactory ssf)
Creates and exports a new UnicastRemoteObject object using the particular
supplied port and socket factories.
static RemoteStub exportObject(Remote obj)
Exports the remote object to make it available to receive incoming calls using an
anonymous port.
static Remote exportObject(Remote obj, int port)
Exports the remote object to make it available to receive incoming calls, using the
particular supplied port.
static Remote exportObject(Remote obj, int port, RMIClientSocketFactory csf,
RMIServerSocketFactory ssf)
Exports the remote object to make it available to receive incoming calls, using a
transport specified by the given socket factory.
static boolean unexportObject(Remote obj, boolean force)
Removes the remote object, obj, from the RMI runtime.

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 5
Deux façons de créer un objet distribué
par héritage : via les constructeur de UnicastRemoteObejct (voir
l'exemple RMI)
par agrégation : via la méthode exportObject (voir l'exemple RMI)

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 6
Les API : java.rmi.registry (1/2)
class LocateRegistry
Cette classe gère en local d'un "serveur" le service de nommage
static Registry createRegistry(int port)
Creates and exports a Registry on the local host that accepts requests on the
specified port.
static Registry createRegistry(int port, RMIClientSocketFactory csf,
RMIServerSocketFactory ssf)
Creates and exports a Registry on the local host that uses custom socket factories
for communication with that registry.
static Registry getRegistry()
Returns a reference to the the remote object Registry for the local host on the
default registry port of 1099.
static Registry getRegistry(int port)
Returns a reference to the the remote object Registry for the local host on the
specified port.
static Registry getRegistry(String host)
Returns a reference to the remote object Registry on the specified host on the
default registry port of 1099.
static Registry getRegistry(String host, int port)
Returns a reference to the remote object Registry on the specified host
port.static Registry getRegistry(String host, int port, RMIClientSocketFactory csf)
Returns a locally created remote reference to the remote object Registry on the
specified host and port.

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 7
Les API : java.rmi.registry (2/2)
Interface Registry
Cette interface permet de créer une autre implémentation du service de
nommage
void bind(String name, Remote obj)
Binds a remote reference to the specified name in this registry.
String[] list()
Returns an array of the names bound in this registry.
Remotelookup(String name)
Returns the remote reference bound to the specified name in this
registry.
Void rebind(String name, Remote obj)
Replaces the binding for the specified name in this registry with the
supplied remote reference.
Void unbind(String name)
Removes the binding for the specified

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 8
Les packages de javax
javax.rmi
javax.rmi.CORBA
Ces deux packages contiennent tous les éléments permettant de mettre
en œuvre RMI-IIOP (AD)

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 9
Le compilateur IDL
En RMI, le compilateur IDL est une fourniture du JDK java que l’on trouve
dans le répertoire bin (exemple sur le JEE 1.5 : C:\Sun\AppServer\jdk\bin)
Il est donc accessible via le PATH
La syntaxe : rmic <package>.<nom classe OD>
La commande rmic permet de générer les squelettes (skelton) et les
amorces (stub) RMI.
<nom classe OD> est le nom de la classe de l’OD (qui hérite de
UnicastRemoteObjetct et surtout hérite d’une interface dans laquelle sont
décrites les méthodes distantes de l’OD
Il est à noter que depuis la version 1.5, il est inutile d’utiliser la commande
rmic car java prend en charge nativement et dynamiquement la création
des objets de classes Stub et Skeleton.
Nous verrons que en RMI-IIOP, il est indispensable d’utiliser la
commande rmic (rmic –iiop …)

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 10
L’adaptateur d’objet (1/2)
Il existe 3 façons d'exécuter un adaptateur RMI :
en utilisant la classe prédéfinie sun.rmi.registry.RegistryImpl
exemple: java -classpath "packages" sun.rmi.registry.RegistryImpl 9999
avantages : un meilleur pilotage du classpath, se lance à l'extérieur
inconvénients : doit toujours être lancé avant tous les autres programmes serveur,
peut être obsolète (confusion avec java.rmi.registry.RegistryImpl), le port est un
paramètre de commande OS
en utilisant la commande rmiRegistry (c'est un exe qui utilise le $CLASSPATH)
exemple: rmiRegistry 9999
avantages : façon récente d'exécuter un adaptateur à l'extérieur
inconvénients : pas de pilotage du classpath, variable d'environnement, le port est
un paramètre de commande OS
en créant l'adaptateur dans le code (le classpath de la JVM)
exemple : try {LocateRegistry.createRegistry(9999);}
catch(Exception l_ex){};
avantages : intégrer au code, le port peut être précisé par configuration (fichier,
properties, …),
inconvénients : intégrer au code, fonction du classpath de la JVM, nécessite un
programme serveur maître devant être exécuté avant tous les autres

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 11
L’adaptateur d’objet (2/2)

On passe en paramètre du lancement le numéro de port sur lequel les


clients devront se connecter.
Ce numéro doit être libre (voir votre administrateur système). Pour vos
applications sur vos PC vous pouvez prendre par exemple un numéro
élevé 9999.
On peut exécuter plusieurs adaptateurs sur une même machine du
moment qu’ils s’exécutent sur des ports différents
L’adresse de connexion à un adaptateur rmi est : rmi://host:port
où host est l’adresse IP de la machine sur lequel s’exécute l’adaptateur
port est le port utiliser par l’adaptateur
rmi est le nom du prôtocole de connexion utilisé (on peut ne pas le
mettre: par défaut rmi)
 Remarque: en ne le mettant pas on peut par une configuration général utiliser un
autre ORB

On ne peut pas enregistrer un OD dans un adaptateur sur une machine


distante depuis une autre machine.

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 12
Le Socket Factory RMI (1/4)

Le Socket Factory de RMI permettant de traiter les requêtes des clients


est de niveau "static"
Le port d'écoute est soit déterminée par défaut (le premier libre),
Le même port pour une même JVM
Un par JVM
soit imposé
UnicastRemoteObject  super( port )
le port doit être libre
on peut associer plusieurs ports
permet de sécuriser l'utilisation des objets distribuées via les firewalls

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 13
Le Socket Factory RMI (2/4)
super()
les ports sont alloués par le système automatiquement
pas de politique ciblé de sécurité
Un seul serveur de socket par JVM

bi
bi

bi
nd
n

n
d

d
bi
nd

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 14
Le Socket Factory RMI (3/4)
super(port)
les ports sont déterminés par l'administrateur
politique ciblé de sécurité
Autant de serveur de socket que de port différent
Attention au conflit de port pour une même machine

bi

bi
nd

bin
bi

nd
nd

d
Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 15
Il semble que le schéma décrit la politique suivante :
dans la JVM1 tous les objets distribués s'exécutent sur le même port
(9101)
dans la JVM2 chaque objet distribué s'exécute sur un port dfférent.

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 16
Le Socket Factory RMI (4/4)

Dans l'exemple NFP214_Exemple_009_ExempleRMI_Security, on


instrumente en la redéfinissant, les classes :
RMIClientSocketFactory
RMIServerSocketFactory
Lors du bind, la classe RMIClientSocketFactory est envoyé (par
sérialisation) à l'adaptateur qui l'enverra ensuite (par sérialisation) au
client lors de sa connexion. Son interface : Socket createSocket(host,port)
La classe RMIServerSocketFactory est utilisée que par le serveur. Son
interface: ServerSocket createServerSocket(port)
Pour obliger le client à utiliser des ports locaux définis (et non aléatoire) il
est nécessaire de redéfinir sa propre politique de socket factory comme
cela est décrit dans l'exemple (voir MyRMISocketFactory.java)

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 17
Création d'un objet distribué en RMI
deux façons :
par héritage
par construction

création par héritage :


la classe UnicastRemoteObject
ne pas oublier super() ou super(port), ….
la meilleur façon de faire
création par construction
la méthode exportObject de UnicastRemoteObject
possède les mêmes signatures que les constructeurs avec en plus l'objet qui
implémente les méthodes distante:
public static RemoteStub exportObject(Remote obj, …)
Attention : dans ce cas, il faut générer le stub avec la commande rmic.

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 18
Mise en œuvre RMI (1/5)
Description dynamique de la mise en œuvre RMI des composants
logiciels du serveur

rmiregistry
9105
NOM_OD
Naming Naming
3 NOM_OD
1

Client
Serveur

2
Stub 2 2
Sekelton
9105
JVM Client JVM Serveur

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 19
Mise en œuvre RMI (2/5)
1 - L'objet serveur s'enregistre auprès du Naming de sa machine
(méthode rebind)
2 - L ’objet skeleton est créé par le Naming, il crée le port de
communication et maintient une référence vers l'objet serveur
3 - Le Naming enregistre l'objet serveur, et le port de communication
utilisé dans du serveur de noms

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 20
Mise en œuvre RMI (3/5)
Description dynamique de la mise en œuvre RMI des composants
logiciels du client

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 21
Mise en œuvre RMI (4/5)
4 - L'objet client fait appel au Naming pour localiser l'objet serveur
(méthode lookup)
5 - Le Naming récupère les "références" de l'objet serveur, ...
6 - crée l’objet Stub et ...
7 - rend sa référence au client
8 - Le client effectue l'appel au serveur par appel à l’objet Stub

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 22
Mise en œuvre RMI (5/5)
Le client effectue l'appel au serveur par appel à l’objet Stub

rmiregistry
9105
NOM_OD

Naming Naming

Client
Serveur

8 8

Stub 8
Sekelton
9105

JVM Client JVM Serveur

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 23
Exemple RMI : Description
Cet exemple correspond en la création d'un seul objet distribué, nommé
HELLO, utilisé par deux clients en parallèle
Il encapsule un objet métier, un Individu composé d'un nom et d'un
prénom
Deux approches fonctionnelles côté serveur :
(cas A) l'objet distribué permet les services suivants :
obtenir un texte de bienvenu correspondant à l'individu en question
changer l'identité de la personne
(cas B) l'objet distribué permet le get et set sur l'Individu
Deux approches fonctionnelles côté client :
en correspondance avec le cas A :
le client 1 demande le texte de bienvenu et l'affiche
le client 2 change l'identité de l'individu
en correspondance avec le cas B :
le client 1 demande l'individu, construit le texte de bienvenu et l'affiche
le client 2 change l'individu

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 24
Exemple RMI : Architecture (cas A)
Le client 1 demande un service au serveur qui réalise le service demandé
Le traitement se fait côté serveur
On est dans un cas "orienté service"
Les clients n'ont pas de copie des objets encapsulés

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 25
Exemple RMI : Architecture (cas B)
Le client 1 demande le contenu de l'objet et en reçoit une copie
Le traitement se fait côté client
On est dans un cas "orienté objet"
Les clients récupèrent une copie de l'objet encapsulé par le serveur

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 26
Exemple RMI : Commentaires (1/2)
Le code est disponible sur le site (réf: NFP214_Exemple_009_ExempleRMI)
Le serveur :
deux scripts pour l'exécuter :
runServeur.bat : l'adaptateur doit être exécuter avant
runServeurEtRegistre.bat : l'adaptateur est exécuter par le serveur.
le programme principal : ExempleRmi.java
crée et exécute l'adaptateur en fonction d'un paramètre
crée l'objet distribué comme un objet quelconque
enregistre l'OD dans l'adaptateur se trouvant au port 9999
l'objet distribué : HelloOD.java
hérite de UnicatRemoteObject
implémente les méthodes distantes de l'interface HelloODInt
encapsule un objet Individu
l'objet Individu
objet quelconque
implémente Serializable pour pouvoir être échangé (cas B) entre le serveur et le
client (inutile dans le cas A)

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 27
Exemple RMI : Commentaires (2/2)
Cas 1, Client 1 :
lookup : connexion sur l'OD
appel à la méthode distante hello() qui retourne la phrase de bienvenue
construite par l'OD
affiche sa valeur si cette dernière change sur le serveur
Cas 1, Client 2 :
lookup : connexion sur l'OD
appel à la méthode distante setIdent(nom,prenom) afin de changer les valeurs
sur l'OD
Cas 2, Client 1 :
lookup : connexion sur l'OD
appel à la méthode distante getIndividu() qui retourne l'individu de l'OD
le client fabrique la phrase de bienvenue
affiche la chaîne si l'individu sur le serveur à changé
 ATTENTION: il faut implémenter la méthode equals de la classe Individu
Cas 2, Client 2 :
lookup : connexion sur l'OD
appel à la méthode distante setIndividu() pour changer l'individu.

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 28
Exemple RMI : Le programme principal (serveur)
public class ExempleRMI
{
public static void main(String args[]) throws Exception
{
if (args.length == 1)
{
if (args[0].equals("registre"))
{
LocateRegistry.createRegistry(9999);
}
}

System.out.println("Création de l'objet distribué");


HelloOD od = new HelloOD("Pierre","DUPONT");

System.out.println("Enregistrement de l'objet distribué");


Naming.rebind("rmi://localhost:9999/HELLO",od);

System.out.println("Bus en ecoute....");

DataInputStream in = new DataInputStream(System.in);


System.out.print("Taper rc, pour arreter le serveur...");
System.out.flush();
String valeur= in.readLine(); Indispensable pour finir la
JVM
Naming.unbind("rmi://localhost:9999/HELLO");
UnicastRemoteObject.unexportObject(od,true /*forcer*/);
}
}

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 29
public class HelloOD extends UnicastRemoteObject implements
Exemple RMI : L'OD HelloODInt
{
private Individu individu;

public HelloOD(String nom,String prenom) throws


RemoteException
{
super();
individu = new Individu(nom,prenom);
}

public String hello()


{
return("HELLO " + individu.getNom() + " " +
individu.getPrenom());
}

synchronized public void setIdent(String nom,String


prenom)
{
individu.setNom(nom);
individu.setPrenom(prenom);
}

public Individu getIndividu()


{
return(individu);
}

public void setIndividu(Individu a_individu)


{
individu = a_individu;
}
}
Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 30
Exemple RMI : L'interface de l'OD

public interface HelloODInt extends Remote


{
// POUR LE CAS A
// =============
public String hello() throws RemoteException;
public void setIdent(String nom,String prenom) throws RemoteException;

// POUR LE CAS B
// =============
public Individu getIndividu() throws RemoteException;
public void setIndividu(Individu a_individu) throws
RemoteException;
}

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 31
Exemple RMI : L'objet

public class Individu implements Serializable


{
String nom;
String prenom;

public Individu(String a_nom,String a_prenom)


{
nom = a_nom;
prenom = a_prenom;
}

public String getNom(){return(nom);}


public String getPrenom(){return(prenom);}
public void setNom(String a_nom){nom=a_nom;}
public void setPrenom(String a_prenom){prenom=a_prenom;}

public boolean equals(Object a_object)


{
if (a_object == null) return false;

Individu l_ind = (Individu)a_object;

return( l_ind.nom.equals(this.nom) &&


l_ind.prenom.equals(this.prenom) );
}
}

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 32
Exemple RMI : Les clients du cas A
public class CasA_Client1
{
public static void main(String args[]) throws Exception
{
HelloODInt helloServices =
(HelloODInt)(Naming.lookup("rmi://localhost:9999/HELLO"));

String messageOld = "";


String message = helloServices.hello();

while(true)
{
if (message.equals(messageOld)==false)
{
System.out.println(message);
messageOld = message;
}
message = helloServices.hello();
}
}
} public class CasA_Client2
{
public static void main(String args[]) throws Exception
{
HelloODInt helloServices =
(HelloODInt)(Naming.lookup("rmi://localhost:9999/HELLO"));

helloServices.setIdent(args[0],args[1]);
}
}

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 33
Exemple RMI : Les clients du cas B
public class CasB_Client1
{
public static void main(String args[]) throws Exception
{
HelloODInt helloObjet =
(HelloODInt)(Naming.lookup("rmi://localhost:9999/HELLO"));

Individu l_individu = helloObjet.getIndividu();


Individu l_individuOld = null;

while(true)
{
if (l_individu.equals(l_individuOld)==false)
{
String message = "BONJOUR : " +
l_individu.getNom() + l_individu.getPrenom();
System.out.println(message);
l_individuOld = l_individu;
}
l_individu = helloObjet.getIndividu();
}
} public class CasB_Client2
} {
public static void main(String args[]) throws Exception
{
HelloODInt helloObjet =
(HelloODInt)(Naming.lookup("rmi://localhost:9999/HELLO"));

Individu l_individu = new Individu(args[0],args[1]);


helloObjet.setIndividu(l_individu);
}
}
Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 34
Exemple RMI : La variante avec exportObject

On utilise exportObject quand la classe de l'OD n'hérite pas de


UnicastRemoteObject
La classe de l'OD implémente toujours l'interface

(voir sur le site l'exemple NFP214_Exemple_009_ExempleRMI_exportObject

HelloOD od = new HelloOD("Pierre","DUPONT");


// HelloOD n'hérite pas de UnicastRemoteObject
UnicastRemoteObject.exportObject(od);
Naming.rebind("rmi://localhost:9999/HELLO",od)
;

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 35
L'atelier 6 : La conversion d'une devise

Cet atelier contient 6 cas graduels de mise en œuvre d'une application


distribué en RMI
L'objectif de cet atelier est de montrer 3 cas de mise en œuvre et leurs
avantages et désavantages
Tous ces cas se compilent en utilisant:
compil.bat
Pour l'exécution :
runOrb.dat (dans une 1ère fenêtre)
runServeur.bat (dans une 2ème fenêtre)
runClient.bat (dans une 3ème fenêtre)

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 36
L'atelier 6 : cas 1 (2/2)
Prenons un cas fonctionnel: la conversion d'une devise.
Une devise est définit par 2 noms de monnaies et le taux permettant de
passer de la première à la deuxième.
La devise est donc une classe Devise.java.
Le service du serveur est de retourner au client un objet devise avec
lequel il peut faire ses conversions.
Cet objet devise est créé dans l'interface et n'est pas connu du serveur.
Cette solution est correcte. Le client ne peut pas changer le taux
(private). L'objet devise est protégé.
Mais on peut y voir un désavantage: si le serveur veut changer le taux
d'une devise, il ne le peut pas.
L'objet devise géré par le client est une copie de celui créé par le serveur.

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 37
L'atelier 6 : cas 1 (1/2)

Méthodes
distantes

convertir1() getDevise(nom) new Devise(…)


convertir2()

Client1 Serveur
ServeurPP

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 38
L'atelier 6 : cas 2
Dans ce cas, le serveur encapsule les 2 devises afin de pouvoir changer
leur taux à tout moment.
Le programme ServeurPP.java permet d'intervenir sur le serveur afin de
changer un des taux des devises.
Une fois le client lancé on s'aperçoit que même si on change le taux côté
serveur, il n'est pas impacté. Il conserve le taux initial car l'objet Devise
appartient à l'espace mémoire du client.
Le client peut changer le taux si l'attribut est accessible (public ou
setteur).

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 39
L'atelier 6 : cas 3
Ce cas permet de montrer comment on peut pallier au désavantage
énoncé précédemment. Le client ne récupère plus des objets Devise
mais il réalise autant de connexion que de serveur.
Le programme ServeurPP crée autant de Serveur qu'il existe de devise à
gérer

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 40
L'atelier 6 : cas 4
Si on analyse la cas précédent, on s'aperçoit que la notion de "Serveur"
correspond à une Devise qui ferait des exportations de services RMI.
Les classes Serveur.java et ServeurInt.java disparaissent et sont
remplacées par les classes Devise.java et DeviseInt.java.
On appelle une instance de la classe Devise un Objet Distribué.

convertir1()
Devise1 setTaux
convertir2()
changer le taux

convertir1() Devise2 setTaux


convertir2()

Client1 ServeurPP

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 41
L'atelier 6 : cas 5
Un désavantage du cas précédent est que le client doit savoir à priori
quelles devises le serveur gère.
Dans le cas 5, le client se connecte au serveur de devise qui gère les
devises et qui permet de signaler au client quelles devises il gère :
la classe Serveur : gère les devises
la classe Devise : gère 1 devise

convertir1()
Devise1 setTaux
convertir2()
changer le taux

convertir1()
Devise2 setTaux
convertir2()

getNomDevises() Serveur

Client1 ServeurPP

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 42
L'atelier 6 : Cas 6

Le même cas précédant mais en utilisant la notion de package et de


répertoire bin de génération.

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 43
Les autres ateliers sur RMI

L'atelier 10 : Visualisation de l'adaptateur


L'atelier 11 : La redondance de serveur (refondu par rapport à celui de l'année dernière)
L'atelier 12 : Le calcul réparti
L'atelier 13 : La référence d'OD et factory en RMI (nouveau)

Cours "Systèmes et réseaux répartis" NFP 214 par Jacques LAFORGUE (jacques.laforgue@neuf.fr) version du 04/02/2010 slide numéro 44

Vous aimerez peut-être aussi