Java RMI
Contenu: Caractéristiques,
A r c h i t e c t u r e , M o d è l e d e
programmation, Service de
nommage, TP.
1
I.FALL, DGI/ESP/UCAD/SN
Janvier 2016
Caractéristiques
n Remote Method Invocation
n Solution Sun pour l'invocation à distance de méthodes
Java
n Inclus par défaut dans le JDK depuis 1.1
¨ (des implantations alternatives (et en logiciel libre) existent
n NinjaRMI (Berkeley)
n Jeremie ObjectWeb)
n …
n Toutes les classes du modèle de programmation dans
java.rmi
n + des outils complémentaires
n (générateur de souches, serveur de noms, démon
d'activation, ...)
2
Caractéristiques
n Un mécanisme de RPC dédié aux objets Java
¨ utilisation de stubs côté client
¨ utilisation de skeletons côté serveur
èmasquent les encodages/désencodages de données et les
communications réseaux
¨ les paramètres locaux de types simples (int, float, ...) sont
transmis par copie
¨ les paramètres de type objet local sont sérialisés et transmis par
copie
¨ les paramètres de type objet distant sont transmis par référence
n Services additionnels
¨ chargement dynamique à distance du code des souches clientes
¨ ramasse-miettes répartis
¨ objets serveurs actifs en permanence ou activables à la
demande
3
Architecture
n Stub/Skeleton : encodage/désencodage des paramètres
(sérialization)
n Remote Ref. Man. : gestion des références distantes RMI
n Transport RMI : protocole client/serveur d'envoi des
messages
¨ (JRMP, IIOP, ...)
4
Architecture
n Prévue pour fonctionner avec différentes types
de liaisons
1. objet distant joignable en point à point
2. objets distants répliqués
3. objets distants joignables par diffusion
n En pratique seul 1 est mis en oeuvre (classe
UnicastRemoteObject)
n Références d'objets distants RMI avec
UnicastRemoteObject
¨ adresse IP
¨ n° port TCP
¨ identifiant local d'objet (entier)
5
Modèle de programmation
n Chaque classe d'objet serveur doit être associée à
une interface
¨ Seules les méthodes de l'interface pourront être invoquées
à distance
n Etapes
1. Ecriture d'une interface
¨ Déclaration des services accessibles à distance
2. Ecriture d'une classe implantant l'interface
¨ Définition du code des services
3. Ecriture du programme serveur
¨ Instanciation et enregistrement de l'objet serveur
4. Ecriture du programme client
¨ Interactions avec le serveur
6
Modèle de programmation
n Ecriture d'une interface
¨ interface Java normale
¨ doit étendre java.rmi.Remote
¨ toutes les méthodes doivent lever java.rmi.RemoteException
7
import java.rmi.Remote;
import java.rmi.RemoteException;
interface CompteInterf extends Remote {
public String getTitulaire() throws RemoteException;
public float solde() throws RemoteException;
public void deposer( float montant ) throws RemoteException;
public void retirer( float montant ) throws RemoteException;
public List historique() throws RemoteException;
}
Modèle de programmation
n Ecriture d'une classe implantant l'interface
¨ classe Java normale implantant l'interface
¨ doit étendre java.rmi.server.UnicastRemoteObject
¨ constructeurs doivent lever java.rmi.RemoteException
n si pas de constructeur, en déclarer un vide qui lève une exception de ce
type
n (modèle pour les anciennes versions de JDK)
8
import java.rmi.server.UnicastRemoteObject;
import java.rmi.RemoteException;
public class CompteImpl extends UnicastRemoteObject implements CompteInterf {
private String nom;
private float solde;
public CompteImpl(String nom) throws RemoteException {super();this.nom = nom;}
public String getTitulaire() { return nom; }
... }
Modèle de programmation
n Ecriture d'une classe implantant l'interface
1. Compilation de l'interface et de la classe avec
javac
n javac CompteInterf.java CompteImpl.java
2. Génération des souches clientes et serveurs
(avant JDK 5)
n à partir du bytecode de la classe avec rmic
¨ rmic CompteImpl
¨ Quelques options utiles de rmic
n -d path répertoire pour les fichiers générés
n -keep conserve le code source des souches générées
n -v1.x souches version JDK 1.x
n -vcompat par défaut, souches pour JDK 1.1,1.2, …
9
Modèle de programmation
n Ecriture d'une classe implantant
l'interface
¨Fichiers générés par rmic
n rmic CompteImpl
¨ CompteImpl_Stub.java : souche cliente
¨ CompteImpl_Skel.java : souche serveur
10
Modèle de programmation
n Ecriture du programme serveur
¨Instanciation de la classe serveur
¨Enregistrement de l'instance dans le serveur
de noms RMI
11
public class Serveur {
public static void main(String[] args) throws Exception {
CompteInterf compte = new CompteImpl("Bob");
Naming.bind("Bob_dist",compte);
}
}
Modèle de programmation
n Ecriture du programme serveur
¨Style Java 5 ou +
12
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class Serveur implements CompteInterf {
private String nom;
private float solde;
public Serveur(String nom) {super();this.nom = nom;}
public String getTitulaire() { return nom; }
...
Modèle de programmation
n Ecriture du programme serveur
¨Style Java 5 ou +
13
...
public static void main(String args[]) {
try { Server obj = new Server(“Bob”);
CompteInterf stub = (CompteInterf ) UnicastRemoteObject.exportObject(obj, 0);
// Bind the remote object's stub in the registry
Registry registry = LocateRegistry.getRegistry(); //default port: 1099
registry.bind("Bob_dist", stub);
System.err.println("Server ready");
} catch (Exception e) {
System.err.println("Server exception: " + e.toString()); e.printStackTrace();
}
}
}
Modèle de programmation
n Ecriture du programme serveur
¨ l'objet compte est prêt à recevoir des
invocations de méthodes
¨ le programme "tourne" en permanence
n tant que compte reste enregistré dans le runtime RMI
¨ (attention : c’est différent du du service de nommage)
¨ pour le désenregistrer
n UnicastRemoteObject.unexportObject(compte,false)
¨ false : on attend que les requêtes en cours soient finies /
true : immédiat
14
Modèle de programmation
n Ecriture du programme client
1. Recherche de l'instance dans le serveur de
noms
2. Invocation des méthodes
15
public class Client {
public static void main(String[] args) throws Exception {
CompteInterf compte =(CompteInterf) Naming.lookup("rmi://localhost/
Bob_dist");
compte.deposer(10);
System.out.println( compte.solde() );
}
}
Modèle de programmation
n Exécution des programmes
1. Lancer le serveur de noms (rmiregistry)
¨une seule fois
¨doit avoir accès au bytecode de la souche
cliente (# CLASSPATH)
2. Lancer le programme serveur
3. Lancer le programme client
17
Modèle de programmation
n Exécution des programmes
1. Lancer le serveur de noms (rmiregistry)
¨start rmiregistry //(Windows)
¨rmiregistry & (Solaris, Unix, …)
¨start rmiregistry 2001 // port 2001
18
Modèle de programmation
n Exécution des programmes
2. Lancer le programme serveur
¨start java -classpath classDir
-Djava.rmi.server.codebase=file:classDir/
Server
¨La console du serveur affiche le message
Server ready
19
Modèle de programmation
n Exécution des programmes
3. Lancer le programme client
¨java -classpath classDir Client
¨La console du client affiche Titulaire du
compte: Bob
20
Modèle de programmation
n Compléments: passage de paramètres avec RMI
¨ types de base (int, float, ...) par valeur
¨ objets implantant java.io.Serializable passés par valeur
(sérialisés)
¨ objets implantant java.rmi.Remote passés par référence
n la référence RMI de l'objet est transmise
¨ d a n s l e s a u t r e s c a s u n e e x c e p t i o n
java.rmi.MarshalException est levée
¨ Ecriture d'une classe d'objet serveurs
n héritage UnicastRemoteObject pas toujours possible
¨ (si classe appartient à une hiérarchie d'héritage)
n è au niveau du programme serveur appel de la méthode
static UnicastRemoteObject.exportObject(Remote)
21
Modèle de programmation
n Compléments: invocations concurrentes
de méthodes RMI
¨Un objet serveur RMI est susceptible d'être
accédé par +sieurs clients simultanément
¨ètjrs concevoir des méthodes RMI thread-
safe
n ie exécutable concurremment de façon cohérente
¨ àla création de thread est faite automatiquement par le
runtime RMI
22
Service de nommage
n Permet d'enregistrer des liaisons entre un
objet serveur et un nom symbolique
¨ accessible localement par les objets serveurs
pour leur enregistrement
n èautant de rmiregistry que de sites serveurs
¨ accessible à distance pour les clients
¨ par défaut sur le port 1099
n (on peut changer : rmiregistry 12345)
¨ noms "plats" (pas de noms composés, pas de
hiérarchies)
23
Service de nommage
n URL RMI
¨ rmi://machine.com:1099/nomSymbolique
n rmi:// et :1099 facultatifs
n machine.com par défaut localhost
n Serveur de noms démarrable
¨ de façon autonome dans un shell avec l'outil
rmiregistry
¨ dans un programme par appel de la méthode
static
n java.rmi.registry.LocateRegistry.createRegistry(int
port)
24
Service de nommage
n Classe java.rmi.Naming (toutes les méthodes sont static)
1. void bind(String,Remote) enregistrement d'un objet
2. void rebind(String,Remote) ré enregistrement d'un objet
3. void unbind(String) désenregistrement d'un objet
4. String[] list(String) liste des noms d'objets enregistrés
5. Remote lookup(String) recherche d'un objet
¨ Les paramètres String correspondent à une URL d'objet RMI
¨ 1 2 3 accessibles localement uniquement
¨ 1 lève une exception si le nom est déjà enregistré
¨ 4 URL du rmiregistry
n Autres méthodes définies dans java.rmi.registry.Registry
¨ Versions récentes de JDK (voir l’exemple Compte précédent)
25
Bibliographie
n Java RMI. W. Grosso. O'Reilly
n Java SE 7 Docs. Oracle
¨http://docs.oracle.com/javase/7/docs/
technotes/guides/rmi/
n ...
26
TP0
n Tester l’exemple du cours
n Etude de cas
¨Concevoir et réaliser un Chatroom (simple)
avec Java RMI
27