Exercice d’application en Java RMI

Programming, Java RMI · exam

Browse all programmation documents

CNAM

Samia Bouzefrane

Exercice d’application en Java RMI

Nous disposons de deux services implantés sous forme d’objets ObjetString et

ObjetCalcul: un qui réalise des opérations sur les chaînes de caractère, l’autre qui réalise

du calcul numérique. Pour simplifier, l’objet ObjetString offre une seule méthode

NbOccurrences qui calcule le nombre d’occurrences d’un caractère dans une chaîne de

caractères (un mot) et l’objet ObjetCalcul offre une seule méthode add qui calcule la

somme de deux nombres. Voici le code de chacune de ces méthodes.

public int add (int a, int b) {

return a+b;

}

public int NbOccurrences(String c, String mot) {

int longueur=ChaineOrigine.length();

int Nb=0;

for (int i=0; i<longueur; i++)

{

if ((ChaineOrigine.substring(i, i+1)).equals(c))

Nb++;

}

}

return Nb;

1. On souhaite rendre chacune de ces méthodes accessibles à distance. Donnez alors la

structure des interfaces qui seront partagées par le serveur et le client sachant que

chaque méthode appartient à un objet distinct.

2. Compléter le code de ces méthodes afin qu’elles puissent gérer les erreurs dues à leur

appel à distance.

3.

Sachant que toute méthode Java appelée par un programme Java distant doit

appartenir à un objet accessible à distance.

Donnez la structure des classes Java qui vont représenter respectivement l’objet

ObjetString et l’objet ObjetCalcul.

4. Si les objets ObjetString et ObjetCalcul doivent être installés sur la machine

clementine.cnam.fr, quelles sont les autres classes Java à implanter sur la

machine clementine. Donnez leur structure générale.

1

Exercices en NFP111

CNAM

Samia Bouzefrane

5. Donnez les commandes à lancer sur la machine clementine afin que les méthodes

add et NbOccurrences puissent être appelées par des clients distants si le service

de noms est activé sur le port 2001.

6. Ecrire le programme du client qui doit être lancé sur une autre machine.

2

Exercices en NFP111

CNAM

Samia Bouzefrane

1. La structure de la classe interface ObjetStringInterface est la suivante. Tous

les champs en gras sont obligatoires.

import java.rmi.Remote;

import java.rmi.RemoteException;

public interface ObjetStringInterface extends Remote {

public int NbOccurrence(String c, String t) throws

RemoteException;

}

La structure de la classe interface ObjetCalculInterface est la suivante :

import java.rmi.Remote;

import java.rmi.RemoteException;

public interface ObjetCalculInterface extends Remote {

Advertisement

public int add(int a, int b) throws RemoteException;

}

2. La méthode add, tout comme NbOccurrences, doit lever l’exception du type

RemoteException pour gérer les erreurs générées suite à un appel distant :

public int add (int a, int b) throws RemoteException {

return a+b;

}

public int NbOccurrences(String c, String mot) throws RemoteException

{

int longueur=ChaineOrigine.length();

int Nb=0;

for (int i=0; i<longueur; i++)

{

if ((ChaineOrigine.substring(i, i+1)).equals(c))

Nb++;

}

}

return Nb;

3. L’objet ObjetString doit contenir la méthode NbOccurrences. De même,

l’objet ObjetCalcul doit définir la méthode add. De plus, pour qu’un objet soit

accessible à distance,

la classe

UnicastRemoteObject et implémenter l’interface correspondante définie en 1.

la classe correspondante doit hériter de

import java.rmi.*;

import java.rmi.server.*;

public class ObjetString extends UnicastRemoteObject implements

ObjetStringInterface

{

public ObjetString() throws RemoteException {

super();

}

3

Exercices en NFP111

CNAM

Samia Bouzefrane

public int NbOccurrence (String c, String ChaineOrigine) throws

RemoteException {

int longueur=ChaineOrigine.length();

int Nb=0;

for (int i=0; i<longueur; i++)

{

if ((ChaineOrigine.substring(i, i+1)).equals(c)) Nb++;

}

return Nb;

} }

import java.rmi.*;

import java.rmi.server.*;

public class ObjetCalcul extends UnicastRemoteObject implements

ObjetCalculInterface

{

public ObjetCalcul() throws RemoteException {

super();

}

public int add (int a, int b) throws RemoteException {

return (a+b);

}

}

4. Sur

Advertisement

la machine clementine, on aura à écrire

et

interface

ObjetStringInterface

classes

ObjetString et ObjetCalcul qui représenteront les objets distribués ainsi que

le serveur Serveur. Comme les autres classes sont déjà données ci-dessus, il reste à

écrire la classe du serveur Serveur.

ObjetCalculInterface,

les classes

les

import java.rmi.*;

import java.rmi.server.*;

public class Serveur {

public static void main(String[] args)

{

try {

System.out.println("Serveur : Construction de

l’implémentation");

ObjetString rev= new ObjetString();

System.out.println("ObjetString lié dans RMIregistry");

Naming.rebind("rmi://clementine.cnam.fr:1099/Mot", rev);

ObjetCalcul r = new ObjetCalcul();

System.out.println("ObjetCalcul lié dans RMIregistry");

Naming.rebind("rmi://clementine.cnam.fr:1099/Addition", r);

System.out.println("Attente des invocations des clients ");

}

catch (Exception e) {

System.out.println("Erreur de liaison de l'objet ObjetCalcul

ou ObjetString");

System.out.println(e.toString());

}

} // fin du main

4

Exercices en NFP111

CNAM

Samia Bouzefrane

} // fin de la classe

5. Si le service de noms doit être activé sur le port 2001 alors il faudra que les objets

ObjetString et ObjetCalcul soient enregistrés sur un rmiregistry de

numéro de port 2001. Comme l’enregistrement est fait par le serveur d’objets, on doit

modifier les lignes suivantes de la classe Serveur :

Naming.rebind("rmi://clementine.cnam.fr:1099/Mot", rev);

...

Naming.rebind("rmi://clementine.cnam.fr:1099/Addition", r);

Par les lignes suivantes :

Naming.rebind("rmi://clementine.cnam.fr:2001/Mot", rev);

...

Naming.rebind("rmi://clementine.cnam.fr:2001/Addition", r);

Les commandes suivantes doivent être lancées sur la machine clementine afin que

les objets ObjetCalcul et ObjetString soient accessibles par des clients

distants :

D’abord compiler les programmes Java (les interfaces, les objets et le serveur).

Clementine> javac *.java

On obtient des fichiers .class

Clementine> ls

ObjetStringInterface.java

Serveur.java

ObjetCalcul.java

Advertisement

ObjetString.java

ObjetCalculInterface.java

ObjetStringInterface.class

Serveur.class

ObjetCalculInterface.class

ObjetString.class

ObjetCalcul.class

fichier.policy

Générer les stubs associés aux objets ObjetCalcul et ObjetString :

Clementine> rmic –v1.2 ObjetCalcul

Clementine> rmic –v1.2 ObjetString

Clementine> ls

ObjetStringInterface.java

Serveur.java

ObjetCalcul.java

ObjetString.java

ObjetCalculInterface.java

fichier.policy

ObjetStringInterface.class

Serveur.class

ObjetCalculInterface.class

ObjetString_Stub.class

ObjetString.class

ObjetCalcul.class

ObjetCalcul_Stub.class

Lancer le service de noms (rmiregistry) qui va accueillir les références des objets

distribués. Mais pour cela, il doit utiliser une politique de sécurité définie dans un

fichier, par exemple fichier.policy.

Clementine>more fichier.policy

grant

{

5

Exercices en NFP111

CNAM

Samia Bouzefrane

permission java.security.AllPermission;

};

Clementine>

A la lecture de fichier.policy, on déduit que rmiregistry accepte une

requête de n’importe quel programme client, sans restriction sur les numéros de port.

L’activation du service de noms nécessite de spécifier le fichier de sécurité utilisé.

Sous Unix/Linux :

Clementine>rmiregistry -J-Djava.security.policy=fichier.policy 2001&

Sous Windows :

Clementine>start rmiregistry -J-Djava.security.policy=fichier.policy 2001&

Une fois le service de noms lancé, on peut lancer le serveur d’objets qui va créer les

objets distribués et qui va les enregistrer auprès de rmiregistry afin que tout

programme client qui demande la référence à un de ces objets puisse l’obtenir en la

demandant au service de noms.

Clementine>java Serveur &

ObjetString lié dans RMIregistry

ObjetCalcul lié dans RMIregistry

Attente des invocations des clients …

6. Voici un exemple de programme client :

import java.io.*;

import java.util.*;

import java.rmi.*;

class Client

{

Advertisement

public static void main (String [] argv) throws IOException

{

int somme=0,Nb=0;

String ligne;

StringTokenizer st;

String c, mot;

System.setSecurityManager(new RMISecurityManager());

BufferedReader entree = new BufferedReader (new

InputStreamReader (System.in));

ligne= entree.readLine();

st = new StringTokenizer (ligne);

c= st.nextToken();

mot=st.nextToken();

try {

ObjetStringInterface s= (ObjetStringInterface) Naming.lookup

("rmi://clementine.cnam.fr:2001/Mot");

somme=s.NbOccurrence(c, mot);

while (st.hasMoreTokens()){

mot=st.nextToken();

Nb=s.NbOccurrence(c, mot);

6

Exercices en NFP111

CNAM

Samia Bouzefrane

ObjetCalculInterface a=

(ObjetCalculInterface)Naming.lookup("rmi://clementine.cnam.fr:2001/Ad

dition");

somme = a.add(Nb, somme);

}

System.out.println(" Dans la phrase /"+ligne+"/, il y a

"+somme+" occurrences de " + c);

}catch (Exception e) {

System.out.println("Erreur d'acces a un objet distant");

System.out.println(e.toString());

}

}

}

Le répertoire du programme client doit contenir les interfaces distantes utilisées par le

client ainsi que les stubs des objets distants, qui sont les représentants locaux de ces

objets.

AutreMachine>ls

Client.java ObjetCalculInterface.class ObjetStringInterface.class

ObjetCalcul_Stub.class

fichier.policy

Objetstring_Stub.class

AutreMachine>javac Client.java

Ensuite lancer l’exécution du client en spécifiant la même politique de sécurité que

celle du registre rmi.

AutreMachine>java –Djava.security.policy=fichier.policy Client

e il etait une fois dans l’ouest

Dans la phrase /e il etait une fois dans l’ouest/, il y a 3

occurrences de e

AutreMachine>

7

Exercices en NFP111