Faculté des Sciences de Tunis
Département des Sciences de l'Informatique AU 2015/2016
Java Remote Method Invocation
Introduction
JAVA et les objets distribués.
Mise en place d’outils facilitant la distribution d’objets et leur utilisation dans
le cadre d’architecture Client/Serveur : RMI.
Extension de la notion de programmation réseau avec les sockets UDP et TCP.
RMI est un système d’objets distribués constitué uniquement d’objets JAVA.
RMI est une API (Application Programming Interface) intégrée à JAVA depuis la
version 1.1.
Java RMI permet de créer des applications réseau où :
Le client et le serveur sont en Java
Le client peut utiliser des objets situés sur le serveur comme s’ils étaient
locaux
La couche réseau devient transparente aux applications client/serveurs
Application RMI : développement coté serveur + développement coté client
Étapes d’un appel de méthode distante
1
Faculté des Sciences de Tunis
Département des Sciences de l'Informatique AU 2015/2016
Développer une application avec RMI : Mise en œuvre
1. Définir une interface distante ([Link]).
2. Créer une classe implémentant cette interface ([Link]).
3. Compiler cette classe (javac [Link]).
4. Créer une application serveur ([Link]).
5. Compiler l’application serveur.
6. Créer les classes stub et skeleton à l’aide de rmic XyyImpl_Stub.java et
XyyImpl_Skel.java (Skel n’existe pas pour les versions >1.2).
7. Démarrage du registre avec rmiregistry.
8. Lancer le serveur pour la création d’objets et leur enregistrement dans rmiregistry.
9. Créer une classe cliente qui appelle des méthodes distantes de l’objet distribué
([Link]).
10. Compiler cette classe et la lancer.
Exemple1 : Application « Echo »
msg1
Client Serveur
[msg1]
Étape 1 : Application serveur (l’interface de l’objet serveur)
Un objet distant doit implémenter l’interface Remote de [Link]
Les méthodes distantes sont celles qui appartiennent à une interface dérivée de la
classe Remote
2
Faculté des Sciences de Tunis
Département des Sciences de l'Informatique AU 2015/2016
Étape 2 : Application serveur (Écriture de l’objet serveur) I
Implémentation de l’interface distante précédente par une classe
Cette classe doit dériver de UnicastRemoteObject qui permet l’invocation de
méthodes distantes
Publication du service offert par le serveur dans le service annuaire
Cet annuaire sera utiliser par les clients pour chercher les services du serveurs
Publication à travers la méthode rebind de la classe Naming :
[Link](String nom, Remote obj)
nom : nom du service
obj : objet serveur
3
Faculté des Sciences de Tunis
Département des Sciences de l'Informatique AU 2015/2016
Étape 3 : Application serveur (Compilation de la partie serveur)
Compilation du fichier [Link] de l’interface interEcho
Compilation du fichier [Link] de la classe srvEcho
Obtention des .class : [Link] et [Link]
Étape 4 : écriture du client
On écrit un client à qui on passe en paramètre l’URL du serveur d’écho et qui :
lit une ligne tapée au clavier
l’envoie au serveur d’écho
affiche la réponse que celui-ci envoie
reboucle en 1 et s’arrête lorsque la ligne tapée est « fin »
4
Faculté des Sciences de Tunis
Département des Sciences de l'Informatique AU 2015/2016
Localisation du service par
serveur=(interEcho) [Link](urlService);
urlService :
rmi://machine:port/nom_service
Étape 5 : Génération des .class nécessaires
Compilation du client et obtention du [Link]
Pour dialoguer avec le serveur le client a besoin d’une image du service serveur
localement c’est le fichier de Stub
5
Faculté des Sciences de Tunis
Département des Sciences de l'Informatique AU 2015/2016
Obtenu par :
Exécution de la commande rmic srvEcho sur le serveur
Obtention de deux fichiers : srvEcho_stub.class et srvEcho_Skel.class
Copie de srvEcho_stub.class et de [Link] avec le client
Côté serveur : Côté client :
[Link] [Link]
[Link] [Link]
srvEcho_stub.class srvEcho_stub.class
Étape 6 :
exécution de l’application sur une même machine
Préparatif : lancement du service d’annuaire
start rmiregistry
Lancement du serveur (à partir du répertoire du serveur)
start java srvEcho
Lancement du client :
java cltEcho rmi://localhost/srvEcho
Exécution sur deux machines différentes
Client Linux : copier dans le même répertoire les .class suivants :
[Link]
[Link]
srvEcho_stub.class
Serveur : dans le même répertoire il faut prévoir les .class suivants :
[Link]
[Link]
srvEcho_stub.class
srvEcho_Skel.class
6
Faculté des Sciences de Tunis
Département des Sciences de l'Informatique AU 2015/2016
Exemple2 : Inversion d’une chaîne de caractères à l’aide d’un objet distribué
Invocation distante de la méthode reverseString() d’un objet distribué qui inverse une chaîne
de caractères fournie par l’appelant.
On définit :
• [Link] : interface qui décrit l’objet distribué
• [Link] : qui implémente l’objet distribué
• [Link] : le serveur RMI
• [Link] : le client qui utilise l’objet distribué
Fichiers nécessaires
Côté Client
- l’interface : ReverseInterface
- le client : ReverseClient
Côté Serveur
- l’interface : ReverseInterface
- l’objet : Reverse
- le serveur d’objets : ReverseServer
Interface de l’objet distribué
- Elle est partagée par le client et le serveur ;
- Elle décrit les caractéristiques de l’objet ;
- Elle étend l’interface Remote définie dans [Link].
Toutes les méthodes de cette interface peuvent déclencher une exception du type
RemoteException.
Cette exception est levée :
- si connexion refusée à l’hôte distant
- ou bien si l’objet n’existe plus,
- ou encore s’il y a un problème lors de l’assemblage ou le désassemblage.
import [Link];
import [Link];
public interface ReverseInterface extends Remote {
String reverseString(String chaine) throws RemoteException;}
7
Faculté des Sciences de Tunis
Département des Sciences de l'Informatique AU 2015/2016
Implémentation de l’objet distribué
• L’implémentation doit étendre la classe RemoteServer de [Link]
• RemoteServer est une classe abstraite
• UnicastRemoteObject étend RemoteServer
- c’est une classe concrète
- une instance de cette classe réside sur un serveur et est disponible via le protocole TCP/IP
import [Link].*;
import [Link].*;
public class Reverse extends UnicastRemoteObject implements
ReverseInterface
{
public Reverse() throws RemoteException {
super();
}
public String reverseString (String ChaineOrigine) throws
RemoteException {
int longueur=[Link]();
StringBuffer temp=new StringBuffer(longueur);
for (int i=longueur; i>0; i--)
{
[Link]([Link](i-1, i));
}
return [Link]();
} }
Le serveur
• Programme à l’écoute des clients ;
• Enregistre l’objet distribué dans rmiregistry
[Link]("rmi://[Link]/MyReverse", rev);
import [Link].*;
import [Link].*;
public class ReverseServer {
public static void main(String[] args)
{
try {
[Link]( "Serveur : Construction de l’implémentation ");
Reverse rev= new Reverse();
[Link]("Objet Reverse lié dans le RMIregistry");
[Link]("rmi://[Link]/MyReverse", rev);
[Link]("Attente des invocations des clients …");
}
catch (Exception e) {
[Link]("Erreur de liaison de l'objet Reverse");
[Link]([Link]());
}
} // fin du main
} // fin de la classe
8
Faculté des Sciences de Tunis
Département des Sciences de l'Informatique AU 2015/2016
Le Client
Obtient une référence d’objet distribué :
ReverseInterface ri = (ReverseInterface) [Link]
("rmi://[Link]/MyReverse");
Exécute une méthode de l’objet :
String result = [Link] ("Terre");
import [Link].*;
import ReverseInterface;
public class ReverseClient
{
public static void main (String [] args)
{ [Link](new RMISecurityManager());
try{
ReverseInterface rev = (ReverseInterface) [Link]
("rmi://[Link]/MyReverse");
String result = [Link] (args [0]);
[Link] ("L'inverse de "+args[0]+" est "+result);
}
catch (Exception e)
{
[Link] ("Erreur d'accès à l'objet distant.");
[Link] ([Link]());
}
}
}