IN328 : RMI
Transcription
IN328 : RMI
IN328 : RMI SI http://personnel.supaero.fr/garion-christophe/IN328 Ce TP va vous permettre de manipuler RMI, l’API d’appel distant fournie par Sun. 1 Objectifs Les objectifs de ce TP sont les suivants : – créer un objet qui fournit des services distants ; – comprendre et manipuler le service de nommage fourni par le JDK ; – comprendre le marshalling et l’unmarshalling ; – comprendre le chargement dynamique des classes. 2 Création d’un objet distant et appel d’une méthode Nous allons dans un premier temps créer un objet qui fournit des services distants. Un client va appeler ces services. Dans un premier temps, ce client se trouvera sur la même machine que l’objet distant, mais même dans ce cas, RMI utilise des sockets. On a donc le même comportement que pour un objet se situant physiquement sur une machine distante. Dans un second temps, nous utiliserons deux machines différentes (vous vous connecterez via ssh sur une machine Sun du CI, comme clervoy par exemple). Important : il faudra placer les bytecodes des applications client et serveur (et pour le registre) dans des répertoires différents pour bien comprendre ce qu’il est nécessaire d’avoir de chaque côté (classes, stubs, interfaces, positionnement du classpath). 1. définir une interface distante InterfaceBonjour qui définit une méthode afficher(String s) ; 2. définir une classe BonjourDistant qui réalise cette interface et qui étend la classe java.rmi.server.UnicastRemoteObject ; 3. créer une classe Enregistrement qui possède une méthode main qui enregistre l’objet dans un registre ; 4. du côté client, implanter une classe AppelDistant qui possède une méthode main qui cherche une référence sur l’objet distant et appelle sa méthode afficher ; 5. générer le stub de la classe BonjourDistant en utilisant l’option -v1.2 de rmic pour ne pas générer de skeleton ; 6. lancer une base de registre grâce à rmiregistry et le serveur. On lancera le registre en prenant de garde de bien positionner le classpath pour que le stub soit visible. 7. lancer le client. Où s’exécute la méthode de l’objet distant ? 3 Passage d’un objet en paramètre Dans cette section, nous allons utiliser une méthode d’un objet distant qui prend en paramètre un objet se situant chez le client. On créera un nouveau paquetage pour pouvoir réutiliser le code écrit précédemment facilement. Important : comme précédemment, nous n’utiliserons pas le chargement dynamique des classes nécessaires. Il faudra donc s’assurer que les classes et stubs nécessaires sont bien dans les classpaths (en particulier, le serveur va avoir besoin de classes dont se sert le client). 1 1. créer une interface InterfaceMessage dans le paquetage du serveur qui définit une méthode getTexte qui renvoie une chaı̂ne de caractères ; 2. créer une classe Message dans le paquetage du client qui réalise cette interface et qui a pour attribut la chaı̂ne de caractères à renvoyer ; 3. modifier les classes précédentes pour que la méthode afficher de InterfaceBonjour prenne un objet de type InterfaceMessage en paramètre. Que se passe-t-il ? 4. écrire une classe MessageSerialisable sérialisable et réalisant InterfaceMessage et l’utiliser dans AppelDistant. Que se passe-t-il maintenant ? 4 Chargement dynamique des classes Dans les sections précédentes, nous avons supposé que le serveur, le client et le registre disposaient des stubs et des bytecodes nécessaires à leur bon fonctionnement. Nous allons maintenant utiliser le chargement dynamique des classes. De cette façon, le serveur et le client ne disposeront que des interfaces distantes nécessaires à leur compilation. 1. récupérer les classes développées dans la section 2 dans deux nouveaux paquetages, fr.supaero.rmi.client.dyn et fr.supaero.rmi.serveur.dyn. Modifier la classe cliente pour que celle-ci puisse utiliser le chargement dynamique des classes ; 2. lancer un registre sans classpath. On a besoin d’un serveur Web pour servir les fichiers. On va utiliser un serveur de fichier léger, disponible sur le site sous l’onglet ressources, la classe ClassFileServer. Pour l’utiliser : java ClassFileServer numPort CHEMIN_VERS_FICHIERS. Lancer ensuite le serveur en précisant comme codebase "http://nomMachineServeurFichier:numPort/" (ne pas oublier le « / » final !). Enfin, lancer le client avec un fichier de politique de sécurité adéquat ; 3. nous allons essayer de « bootstrapper » le client et le serveur. Pour cela, créer un répertoire qui contiendra les classes de l’application (même celles du client. Il faudra donc modifier la classe AppelDistant pour qu’elle n’ait plus de méthode main, mais qu’elle appelle la méthode afficher à sa création), et deux applications qui chargent dynamiquement la classe applicative du serveur et la classe applicative du client. 5 Utiliser le mécanisme d’activation Dans cette section, il faut essayer d’étendre non pas UnicastRemoteServer pour la classe représentant l’objet distant, mais Activatable. 1. modifier la classe BonjourDistant pour qu’elle étende correctement Activatable ; 2. modifier la classe Enregistrement pour qu’elle enregistre l’objet Activatable. Ne pas oublier de mettre en place un RMISecurityManager ; 3. lancer l’application en utilisant un « client de base » précédemment développé. Attention à la politique de sécurité pour rmid. 2