• Aucun résultat trouvé

4.1 Aperçu des paquetages

– 4 paquetages pour les rmi : – java.rmi,

– java.rmi.server, – java.rmi.registry, – java.rmi.dgc

– java.rmi: classes, interfaces et exceptions coté client.

– java.rmi.server : classes, interfaces et exceptions coté serveur. Classes utilisées lorsqu’on écrit des objets distants utilisés par des clients.

– java.rmi.registry: classes, interfaces et exceptions utilisées pour localiser et nommer des objets distants.

– java.rmi.dgc : gestion du ramasse-miettes distribué (dgc, ou Distributed Grabage Collector).

VII.4 – Implantation 141 – ☛ Dans la suite, et conformément à la documentation Sun, on utilisera l’adjectif distant en se référant implicitement à un serveur et l’adjectif local en se référant à un client.

4.2 Implantation du serveur

– Pour créer un nouvel objet distant, on définit une interface qui étend java.rmi.Remote.

– L’interface Remoten’a aucune méthode. Elle agit comme un marqueur d’ob- jets distants.

– L’interface enfant de Remoteque l’on définit détermine quelles méthodes de l’objet distant à créer peuvent être appelées par les clients.

– Seules les méthodes publiques déclarées dans une interface distante peuvent être appelées de manière distante.

– Chaque méthode de l’interface enfant de Remote définie par le pro- grammeur doit déclarer lever l’exception java.rmi.RemoteException. – Exemple d’une interface pour un “Hello World” distant. Cette interface a

une seule méthode, parler() import java.rmi.*;

public interface DoueDeParole extends Remote {

public String parler() throws java.rmi.RemoteException; }

– Après avoir défini une interface distante, il faut définir une classe qui implante cette interface et étend java.rmi.UnicastRemoteObject. – La classe UnicastRemoteObject fournit un certain nombre de méthodes qui

se chargent des détails de la communication distante. – En particulier, il y a le découpage et le rassemblement.

– Découpage (marshaling) : conservion des arguemnts et des valeurs de retour en un flux d’octets qui peuvent être envoyés à travers le réseau.

– Exemple de BashoServeur, une classe qui implante l’interface distante DoueDeParole et qui étend UnicastRemoteObject

import java.rmi.*;

import java.rmi.server.*; import java.net.*;

public class BashoServeur extends UnicastRemoteObject implements DoueDeParole { public BashoServeur() throws RemoteException {

}

public String parle() throws RemoteException {

return "La cloche du temple s’est tue " + "\n" "Dans le soir, le parfum des fleurs " + "\n" "En prolonge le tintement. " + "\n" "Matsuo Basho (1644-1694)" ;

}

public static void main(String args[]) { try {

BashoServeur b = new BashoServeur(); Naming.rebind("MatsuoBasho", b);

System.out.println("Serveur BahoServeur pret."); } catch (RemoteException re) {

System.out.println("Exception ds BashoServeur.main() : " + re); } catch (MalformedURLException re) {

System.out.println("MalformedURLException ds BashoServeur.main() : " + re);

} }// main() }

– Le constructeur BashoServeur() appelle le constructeur par défaut. Pour une classe Java locale, ceci n’a pas besoin d’etre écrit. Ici, on doit déclarer que toute méthode lève RemoteException.

– Notez bien qu’ici le code de la méthode distante quoiDire() n’est pas différent de celui qui serait écrit pour une application entièrement locale.

Ceci est un gros avantage des RMI : les aspects distants sont pour la plupart transparents pour le programmeur.

– Notez que les méthodes main()et BashoServeur()ne seront pas disponibles de manière distante. Seule quoiDire() l’est (parce que figurant dans une interface Remote).

– Le constructeur est trivial mais doit figurer, afin de déclarer qu’il lève une RemoteException.

– Il y a enregistrement de l’objet BashoServeur via un Naming.rebind(). Cette méthode place les objets dans un registre et leur associe un nom fourni en paramètre.

– Un client peut ensuite requérir cet objet par son nom ou obtenir une liste d’objets disponibles.

VII.4 – Implantation 143

4.3 Génération des souche et squelette

– On génère la souche (stub) et le squelette (skeleton) via rmic, que l’on applique aux .class Par ex.

/home/mounier > rmic BashoServeur /home/mounier > ls Doue* BashoServeur*

BashoServeur.class BashoServeur_skel.class DoueDeParole.class BashoServeur.java BashoServeur_stub.class DoueDeParole.java – Arguments : rmic BashoServeur -d -classpath JavaProgs/Tests L’option

-dva mettre le .class dans le répertoire où le source est trouvé (par défaut, le .class est placé dans le répertoire courant).

4.4 Lancement du serveur

– Pour lancer le serveur :

– On lance d’abord le serveur de registre, avec lequel le serveur dialogue : rmiregistry &(ou start rmregistry sous DOS). Il écoute sur le port 1099 par défaut. Pour qu’il écoute sur un autre port : rmiregistry 2048 &

– On lance ensuite le serveur,

/home/mounier > java BashoServeur & Serveur BashoServeur pret.

4.5 Implantation du client

– Pour qu’un client appelle une méthode distante, il doit récupérer une réfé- rence à un objet distant.

– Pour cela, il récupère un objet distant en demandant au serveur de recher- cher dans un registre. La demande s’effectue au travers de la méthode lookup(String name)qu’appelle le client.

– Le schéma de nommage dépend du registre utilisé. La classe Naming du paquetage java.rmi fournit un schéma fondé sur des URL pour localiser des objets.

– L’obtention de référence distante se fera alors par :

Object o1 = Naming.lookup("rmi://sunsite.unc.edu/MatsuoBasho"); Object o2 = Naming.lookup("rmi://sunsite.unc.edu:2048/MatsuoBasho"); – Le champ de protocole est ici rmi, qui signifie que l’URL référence un objet

distant.

– Le champ fichier (ici MatsuoBasho) spécifie le nom de l’objet distant. – Les champs de nom de machine et de numéro de port optionnel sont in-

– Puisque la méthode lookup() renvoie un Object, il faut effectuer une conversion de type (cast) en le type d’interface distante que l’objet distant implante (et non la classe elle-même, cachée des clients) : DoueDeParole b = (DoueDeParole) Naming.lookup("MatsuoBasho") ;

– Exemple de client associé à BashoServeur : import java.rmi.*;

public class BashoClient {

public static void main(String args[]) {

System.setSecurityManager(new RMISecurityManager()); try {

DoueDeParole b = (DoueDeParole) Naming.lookup("MatsuoBasho"); String message = b.parle();

System.out.println("BashoClient : " + message); } catch (Exception e) {

System.out.println("Exception dans BashoClient.main() : " + e);

} } }