TP Java RMI

Frank Singhoff

SOMMAIRE

·        I. Exemple de programme

o        I.1 L'application

o        I.2 Questions

·        II. Utilisation élémentaire

·        III. Usine à objets

·        IV. Objets sérialisables

·        V. Exercice de synthèse

·        VI. Corrections

I. Exemple de programme

I.1 L'application

Récupérez les fichiers de ce premier exercice à partir de ce répertoire . Sauvez tous ces fichiers dans un répertoire EXO1. Nous allons regarder les trois fichiers source suivant :

 
Hello.java     HelloServeur.java   HelloClient.java    

Environnement Java :
Avant de faire ce TP, exécutez un des scripts java.zsh (si vous utilisez BASH ou ZSH) ou java.tcsh (si vous utilisez TCSH ou CSH). Cette opération doit être effectuée avant de lancer javac, java, rmiregistry ou rmic.

Par exemple, en bash, taper :
source java.zsh




On commente ici le contenu de Hello.java, l'interface :

 
public interface Hello extends java.rmi.Remote
{
    String lireMessage() throws java.rmi.RemoteException;
}

Remote signifie que la méthode lireMessage de cette classe Hello pourra être appelée depuis une JVM autre que la JVM locale.

HelloServeur.java implémente cette interface :

 
public class HelloServeur extends UnicastRemoteObject
      implements Hello

 

Pour compiler ces trois fichiers, faire :

 
javac *.java
 

On obtient alors  :

 
Hello.class    HelloServeur.class  HelloClient.class   
 

Pour avoir la souche pour les clients et le squelette pour les serveurs, faire :

 
rmic -vcompat  HelloServeur
 

Ce qui produit les deux fichiers suivants :

 
HelloServeur_Skel.class     HelloServeur_Stub.class
 

Notez que les codes sources de la souche et du squelette sont cachés : pour obtenir ces codes sources, invoquer rmic avec l’option keep

 

Maintenant, en étant dans le répertoire où se trouvent les fichiers .class :

Ainsi, sur la machine localhost  :

 
rmiregistry 20000&
java -Djava.security.policy=java.policy HelloServeur  20000 coucou
 

le serveur répond :

 
HelloServeur enregistre : //localhost.univ-brest.fr:20000/HelloServeur
 

Sur cette même machine, depuis le même répertoire :

 
java -Djava.security.policy=java.policy HelloClient  20000 localhost
 

le client répond :

 
 Connexion au service : //localhost.univ-brest.fr:20000/HelloServeur
 

On voit alors apparaître la message coucou émis par le serveur.

Remarque :
Là où se trouvent les sources, il y a un fichier Makefile qui automatise les commandes précédentes...

 

I.2 Questions

Pour faciliter la résolution des exercices suivants, répondez aux questions suivantes :

  1. Identifiez dans le programme l'instanciation de l'objet, son activation et sa publication vers le serveur de noms ?
  2. Identifiez dans le programme la récupération de la souche et l'invocation du service de noms.
  3. A quoi sert le fichier java.policy ?
  4. A quoi sert le fichier MyHostName.java ?
  5. Etudiez les souches et squelettes : identifiez l’invocation de l’objet d’implémentation ainsi que la création/manipulation de la requête.



II. Utilisation élémentaire de RMI

Récupérez les fichiers de cet exercice à partir de ce répertoire . Sauvez tous ces fichiers dans un répertoire EXO2. Dans ce premier exercice, on vous demande d'implanter un serveur permettant de gérer un compte bancaire. Le serveur propose une interface (voir le fichier Compte.java) qui permet aux clients de :

Travail à faire :



III. Usine à objets

Récupérez les fichiers de cet exercice à partir de ce répertoire . Sauvez tous ces fichiers dans un répertoire EXO3. On regarde comment construire une usine à objets avec Java RMI. Une usine à objets est un objet invocable à distance dont la fonction est d'instancier d'autres objets invocables à distance.

On se propose d'illustrer la notion d'usine en réalisant un programme dont le but est d'instancier des piles d'entier. Pour ce faire, vous devez implanter les interfaces UsinePile et Pile.

La méthode creation_pile de l'interface UsinePile permet de créer des objets de type Pile. Chaque objet de type Pile doit être publié au service de nom grâce au nom passé en argument lors de l'appel de la méthode creation_pile. Les piles ainsi créées stockent des entiers. On suppose qu'une pile à une taille maximale précisée à sa création.

L'interface Pile permet de manipuler une pile après sa création. On y trouve les méthodes classiques :

Travail à faire :




IV. Objets sérialisables



Récupérez les fichiers de cet exercice à partir de ce répertoire . Sauvez tous ces fichiers dans un répertoire commun EXO4.

Une des particularités de Java RMI est la possibilité de transférer des objets par copie entre les clients et les serveurs (ce qui n'est pas possible avec CORBA). Les objets échangés par copie doivent implanter une interface qui étend l'interface standard Serializable : on parle d'objets sérialisables ("mise en série" des données). Attention : les objets sérialisables ne peuvent pas être invoqués par un client situé sur une machine distante. : ils sont passés par copie au client !

Nous illustrons ce point en reprenant l'exercice III mais cette fois-ci, il ne s'agit plus de gérer des piles mémorisant des entiers : les piles mémorisent maintenant des objets implantant l'interface PileDonnee. Pour ce faire, vous disposez d'une nouvelle version de l'interface Pile.

Travail à faire :




V. Exercice de synthèse



Ce dernier exercice fait la synthèse des exercices précédents. L'application à réaliser est constituée d'objets accessibles à distance (objets RemoteObject) et d'objets passés par copie (objets Serializable). Il s'agit de mettre en place une application qui mémorise les résultats académiques d'un ensemble d'étudiants.

Pour ce faire, récupérez les fichiers de cet exercice à partir de ce répertoire. Sauvez ces fichiers dans un répertoire commun EXO5.

Cette application est constituée de deux interfaces : Etudiant.java et Promotion.java. L'interface Etudiant.java donne accès aux données associées à un étudiant : c'est à dire son nom, son prénom, son numéro d'étudiant ainsi qu'un ensemble de notes. Chaque étudiant passe plusieurs épreuves. Chaque épreuve donne lieu à une note. Chaque note est associée à un coefficient. Un coefficient est une donnée de type double dont la valeur est comprise entre 0 et 1. La somme des coefficients de toutes les épreuves d'un étudiant doit être égale à 1. Ces différentes épreuves sont stockées dans un ensemble d'instance de la classe Epreuve_avec_coeff.java. L'interface Etudiant.java propose trois méthodes:


L'interface Promotion.java permet:

Travail à faire :





Page maintenue par Frank Singhoff(singhoff@univ-brest.fr)
Dernière mise à jour le 1 septembre 2015