Académique Documents
Professionnel Documents
Culture Documents
Cours RMI
Cours RMI
Java
RMI : Remote Method Invocation
Onfroy Brice
1 Introduction
RMI (Remote Method Invocation ) est une API Java permettant de manipuler des objets
distants (c'est-à-dire un objet instancié sur une autre machine virtuelle, éventuellement sur une
autre machine du réseau) de manière transparente pour l'utilisateur, c'est-à-dire de la même façon
que si l'objet était sur la machine virtuelle (JVM ) de la machine locale.
Ainsi un serveur permet à un client d'invoquer des méthodes à distance sur un objet qu'il
instancie. Deux machines virtuelles sont donc nécessaires (une sur le serveur et une sur le client)
et l'ensemble des communications se fait en Java.
On dit généralement que RMI est une solution "tout Java", contrairement à la norme Corba
de l'OMG (Object Management Group ) permettant de manipuler des objets à distance avec
n'importe quel langage. Corba est toutefois beaucoup plus compliqué à mettre en oeuvre, c'est la
raison pour laquelle de nombreux développeurs se tournent généralement vers RMI.
Les connexions et les transferts de données dans RMI sont eectués par Java sur TCP/IP
grâce à un protocole propriétaire (JRMP, Java Remote Method Protocol ) sur le port 1099.
A partir de Java 2 version 1.3, les communications entre client et serveur s'eectuent grâce au
protocole RMI-IIOP (Internet Inter-Orb Protocol ), un protocole normalisé par l'OMG (Object
Management Group ) et utilisé dans l'architecture CORBA.
La transmission de données se fait à travers un système de couches, basées sur le modèle OSI
an de garantir une interopérabilité entre les programmes et les versions de Java.
Puisque les objets Voiture et Roue seront distanciés du point de vue du client, celui-ci devra
connaître ce qu'il est possible de faire au garage. Ainsi, chez le client, en plus d'avoir la classe
Client (décrivant l'objet Client), il disposera de 2 interfaces Voiture et Roue. Elles présisent les
méthodes disponibles sur les objets distants. Le client manipulera donc des objets Voiture et
Roue (objets de type nom de l'interface implémentée sur le serveur).
Pour que ces objets (distants) soient accessibles depuis le client, ils devront être enregistrés
dans un annuaire d'objets appelé rmiregistry. Cet annuaire contient la liste de tous les objets
disponibles sur le serveur. Ces objets sont distingués par leur nom (type String). De ce fait, à la
construction de chaque objet (appel au constructeur), le nouvel objet devra obligatoirement être
enregistré dans l'annuaire si l'on souhaite y avoir accès à distance.
Pour simplier l'écriture des types des objets, on choisira d'appeler l'interface Voiture et
Roue, les classes implémentant ces interfaces s'appelleront respectivement VoitureImplemen-
tation et RoueImplementation.
Note : Rappelons qu'il n'est pas possible de dénir de constructeur dans une interface.
Ainsi, on devra écrire une méthode retournant l'identiant de l'objet (type String) faisant appel
au constructeur déni dans la classe.
1
ONFROY Brice RMI : Remote Method Invocation
Si, par exemple, le client souhaite une autre voiture, il fera appelle à la méthode getNew-
Voiture qui lui retournera le nom sous lequel l'objet Voiture a été enregistré dans l'annuaire.
Puisque les objets que le client souhaite manipuler sont distants, il n'a pas connaissance de
la liste des objets auxquels il a accès. Le morceau de code suivant permet d'obtenir, du serveur,
la liste des objets enregistrés.
Lorsque l'on dispose de la liste des objets distants, il est maitenant possible d'acquérir un
pointeur sur chacun de ces objets. Le morceau de code suivant permet d'obtenir ce type de pointeur
sur l'un des objets distants.
Si le client souhaite créer une nouvelle voiture dans son garage favoris, sans bouger de son
fauteuil, il fera ainsi :
2
ONFROY Brice RMI : Remote Method Invocation
import java.rmi.Naming;
// l'adresse du serveur devra être passé en paramètre à l'exécution du client
public class Client
{
public static void main( String [] args )
{
try{
// on récupère la liste des noms des objets disponibles
String [] objetsDispo = Naming.list( "rmi://" + args [0] );
for( String o : objetsDispo )
{
System.out.println( o );
}
// on récupère un pointeur sur le premier objet Voiture
Voiture voiture = (Voiture) Naming.lookup( objetsDispo [0] );
// voiture.getRoue() retourne un pointeur sur l'objet
// Roue de l'objet voiture courant
System.out.println( voiture.getRoue().getCouleur() );
voiture.getRoue().setCouleur( "vert" );
System.out.println( voiture.getRoue().getCouleur() );
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.*;
3
ONFROY Brice RMI : Remote Method Invocation
{
RoueImplementation roue;
4
ONFROY Brice RMI : Remote Method Invocation
import java.rmi.*;
import java.io.Serializable;
import java.rmi.*;
import java.rmi.server.*;
String couleur;
int id = ID++;
Simulons la situation exposée au début de ce papier en plaçant sur un poste garage les
chiers Voiture.java, VoitureImplementation.java, Roue.java et RoueImplementation.java et sur
un autre poste client les chiers Client.java Roue.java et Voiture.java.
Compilons tout çà : javac ∗ .java.
Sur le poste garage, exécutons notre classe frontale : javaV oitureImplementation‘
Sur le poste client, exécuton notre client : javaClientgarage
5
ONFROY Brice RMI : Remote Method Invocation
6 Points de détails
Dans notre exemple, la classe VoitureImplementation frontalise (est composée de) la classe
RoueImplementation, ainsi, les objets RoueImplementation doivent être sérialisables an qu'ils
soient accessibles à distance.
Au lieu de lancer l'annuaire RMI dans un terminal, il est possible de le lancer directement
par le code en spéciant un numéro de port d'écoute (par défaut : 1099).
java.rmi.registry.LocateRegistry.createRegistry(1099);
L'annuaire RMI doit être lancé par la classe frontale, ici, VoitureImplementation.
Dans notre exemple, on a écrit une méthode getNewVoiture() qui permet, à partir d'un
objet Voiture existant, d'obtenir un nouvel objet distant. Faisons un petit zoom sur cette méthode :