Transparents - Département Informatique et Réseaux
Transparents - Département Informatique et Réseaux
Transparents - Département Informatique et Réseaux
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Intergiciels – RMI, JMS, CORBA<br />
A. Diaconescu<br />
B. Dupouy<br />
L. Paut<strong>et</strong><br />
http://perso.telecom-paristech.fr/~diacones/comasic
Rappel<br />
Système Reparti<br />
<strong>et</strong><br />
Intergiciel<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy 2
Rappel : système réparti<br />
• Système constitué de multiples ressources informatiques (ex:<br />
processus logiciels, équipements matériels, …) interconnectées<br />
via un support de communication (ex: réseaux, communication<br />
interprocessus, mémoire partagée, …)<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy 3
Rappel : modèle OSI <strong>et</strong> TCP/IP<br />
OSI<br />
TCP-IP<br />
TCP-IP<br />
Application<br />
Présentation<br />
Application<br />
Application<br />
Session<br />
Transport<br />
TCP / UDP<br />
Sock<strong>et</strong>s<br />
Sock<strong>et</strong>s<br />
TCP / UDP<br />
Réseau<br />
IP<br />
IP<br />
Liaison<br />
Ethern<strong>et</strong><br />
Ethern<strong>et</strong><br />
Physique<br />
Ethern<strong>et</strong><br />
Ethern<strong>et</strong><br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy 4
Des sock<strong>et</strong>s aux intergiciels<br />
• Limites de l’API sock<strong>et</strong> :<br />
• Solution :<br />
• Travail fastidieux, répétitif, suj<strong>et</strong> aux erreurs : configuration,<br />
construction de requêtes, déploiement, exécution<br />
• Factoriser les opérations sur les sock<strong>et</strong>s à l’aide de bibliothèques<br />
de plus haut niveau<br />
• Intergiciel (« middleware ») : abstractions pour la répartition<br />
• Fournit un modèle de répartition : entités inter-agissantes suivant<br />
une sémantique claire<br />
• Au dessus des briques de base de l’OS (dont les sock<strong>et</strong>s)<br />
• Définit un cadre compl<strong>et</strong> pour la conception <strong>et</strong> la construction<br />
d’applications distribuées<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy page 5
Intergiciels - définitions de base<br />
• Logiciel réutilisable qui fait la médiation entre les<br />
applications <strong>et</strong> le réseau<br />
• Gère <strong>et</strong> facilite l’implantation de l’interaction entre<br />
des applications qui s’exécutent sur des platesformes<br />
distantes <strong>et</strong>/ou hétérogènes<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy page 6
Intergiciel – positionnement (1)<br />
• Au dessus du réseau<br />
• En dessous des applications (logique de business), bases de données, …<br />
• Sur toutes les machines participantes<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy 7
Intergiciel – positionnement (2)<br />
• L’intergiciel - où se trouve-t-il<br />
par rapport au modèle OSI<br />
Application<br />
Transport<br />
Réseau<br />
Liaison<br />
Physique<br />
Services Application<br />
Services Intergiciel<br />
Services Réseau<br />
Réseau<br />
Application<br />
Transport<br />
Réseau<br />
Liaison<br />
Physique<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
8
Intergiciel - contenu<br />
• Une collection réutilisable <strong>et</strong> extensible de services<br />
non-fonctionnels<br />
• A l’origine : des services de communication<br />
• Et ensuite : nommage, transactions, sécurité, persistance,<br />
gestion d’instances, journalisation (logging), …<br />
Un service non-fonctionnel n’est pas conscient des buts fonctionnels<br />
(de business) <strong>et</strong> de la sémantique de l’application qu’ils servent<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
9
Intergiciels – importance (1)<br />
• Aide à définir <strong>et</strong> concevoir un système réparti<br />
• Aide les développeurs, en les protégeant :<br />
• des détails liées à la plateforme sous-jacente<br />
• des difficultés liées à la distribution<br />
• Amortit les coûts de développement initiaux par la<br />
réutilisation <strong>et</strong> par la dissémination de l’expertise<br />
• Communication : création de session, (de)marshalling, collecte <strong>et</strong> « bufferisation » de<br />
requêtes, contrôle de la concurrence, …<br />
• D’autres services non-fonctionnels : nommage, transactions, sécurité, …<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
page 10
Intergiciels – importance (2)<br />
• Aide à l’intégration d’applications existantes<br />
• Certains intergiciels perm<strong>et</strong>tent la communication entre<br />
des obj<strong>et</strong>s répartis hétérogènes, indépendamment des:<br />
• langages de programmation<br />
• systèmes d’exploitation<br />
• plates-formes d’exécution<br />
• fournisseurs de technologie<br />
• protocoles réseau<br />
• formats des données<br />
• Mais, de nombreux intergiciels restent spécifiques à un<br />
langage, un vendeur, un OS, …<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy 11
Intergiciels - Types<br />
• Modèles de communication<br />
• RPC - appel de procédure/méthode<br />
• MOM - envoie de messages (point-à-point, publish/subscribe)<br />
• Streaming<br />
• Hétérogénéité<br />
• Approche dépendante du langage de programmation<br />
• RMI (pour Java), Modula-3 (pour Modula), DSA (pour Ada)<br />
• Approche indépendante du langage de programmation<br />
• CORBA (de l’OMG), DCOM / .NET (de Microsoft)<br />
• Modèle de programmation<br />
• Orienté Obj<strong>et</strong> – ex : RMI, JMS, CORBA, DCOM,<br />
• Orienté Composant – ex : CCM, JavaEE, .N<strong>et</strong>,<br />
• Orienté Service - ex : Web services,<br />
• Composants Orientés Service – ex : OSGi, iPOJO, SCA<br />
• …! …<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy 12
Java RMI<br />
- Remote M<strong>et</strong>hod Invocation -<br />
Ressources :<br />
‣ http://docs.oracle.com/javase/tutorial/rmi/index.html<br />
‣ http://docs.oracle.com/javase/6/docs/technotes/guides/rmi<br />
…<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
13
Objectifs de Java RMI<br />
• Définir une architecture distribuée qui s'intègre dans le<br />
langage Java de façon transparente, donc qui perm<strong>et</strong>te :<br />
• L'invocation de méthodes sur des obj<strong>et</strong>s situés sur des machines<br />
virtuelles différentes, de façon similaire à une invocation locale;<br />
• L'utilisation de l'environnement de sécurité Java classique lors de<br />
l'exécution d'applications distribuées;<br />
• L'affranchissement du programmeur de la gestion de la mémoire,<br />
en définissant une extension distribuée au garbage collector.<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
page 14
Architecture RMI<br />
Interface - principe important<br />
• Séparation de deux concepts :<br />
• Définition d’un comportement – Java Interface<br />
• Implantation d’un comportement – Java Class<br />
• Dans un système réparti :<br />
• Le client s’intéresse à la description d’un service – Interface<br />
• Le serveur fournit l’implantation - Class<br />
Système<br />
RMI<br />
Programme Client<br />
Interface<br />
Programme Serveur<br />
Implantation<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
15
Architecture RMI – plusieurs couches<br />
• Souches (stubs) <strong>et</strong> Squel<strong>et</strong>tes (skel<strong>et</strong>ons)<br />
• Juste en dessous du programme développeur<br />
• Transforment les appels Java en messages réseau<br />
• …<br />
• Couche de Transport<br />
• Fait la connexion entre les JVMs<br />
• Utilise le protocole TCP/IP<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
16
• Stub (Souche)<br />
Architecture RMI<br />
• Fait la transition entre l’appel du client <strong>et</strong> le réseau<br />
• Skel<strong>et</strong>on (Squel<strong>et</strong>te)<br />
• Fait la transition entre le réseau <strong>et</strong> l’appel vers l’Obj<strong>et</strong> Serveur<br />
> Visibles ou invisibles par le développeur, selon la version de JDK<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
=<br />
Interface<br />
m<strong>et</strong>hode1()<br />
m<strong>et</strong>hode2() 17
Obj<strong>et</strong> réparti – RMI<br />
- stubs <strong>et</strong> skel<strong>et</strong>ons -<br />
• Extension du mécanisme d’appels de méthodes à la<br />
répartition :<br />
• Obj<strong>et</strong> « proxy » qui reprend la même signature que l’Obj<strong>et</strong><br />
Serveur : souche (« stub »), manipulé par le client,<br />
• Code côté serveur pour traiter la requête, <strong>et</strong> transm<strong>et</strong>tre la<br />
réponse à l’Obj<strong>et</strong> Client (« skel »),<br />
• RMI + JVM ajoutent la logique de traitement de la requête :<br />
localisation de l’obj<strong>et</strong>, construction de la requête,<br />
transmission, …<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
page 18
Obj<strong>et</strong> réparti – RMI<br />
- terminologie <strong>et</strong> définitions -<br />
• Un obj<strong>et</strong> distant (Remote Object) est un obj<strong>et</strong> dont les méthodes peuvent<br />
être invoquées par des clients situés sur des JVM différentes<br />
(logiquement/physiquement),<br />
• C<strong>et</strong> obj<strong>et</strong> distant est manipulé au travers d’interfaces, appelées Remote<br />
Interfaces qui listent les méthodes que les clients pourront invoquer sur<br />
ces obj<strong>et</strong>s distants,<br />
• Une référence distante (Remote Reference) est une référence qui perm<strong>et</strong><br />
d'adresser un obj<strong>et</strong> situé sur une JVM différente,<br />
• Une invocation de méthode distante (Remote M<strong>et</strong>hod Invocation) appelle<br />
une méthode définie dans une interface d'obj<strong>et</strong> distant. Elle a la même<br />
syntaxe qu'une invocation de méthode locale.<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
page 19
Passage d’appels distants<br />
Obj<strong>et</strong>s s’exécutant sur :<br />
• La même JVM - appel local<br />
• Des JVMs différentes sur la même machine – appel distant<br />
• Passant par la couche réseau de la machine<br />
• Des machines différentes – appel distant<br />
• Passant par une connexion réseau entre les machines<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
20
• Récapitulatif :<br />
Obj<strong>et</strong> réparti - RMI<br />
Appelant<br />
Appelé<br />
Appelant<br />
Appelé_Stub<br />
Appelé<br />
Appelé_Skel<br />
JVM<br />
RMI + JVM<br />
Appel local<br />
(même JVM)<br />
Appel distant<br />
(JVMs differentes)<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
page 21
Différence appel local/distant<br />
• Les clients manipulent des proxies qui implémentent les remote interfaces<br />
(pas directement les obj<strong>et</strong>s qui implémentent ces interfaces),<br />
• Les paramètres de type simple (int, …) sont passés par copie,<br />
• Les obj<strong>et</strong>s locaux sont sérialisés (serializable) <strong>et</strong> passés par copie pour être<br />
envoyés : différence avec le modèle de Java, dans lequel les obj<strong>et</strong>s sont<br />
passés par référence,<br />
• Les obj<strong>et</strong>s distants sont passés par référence : les méthodes sont bien<br />
exécutées sur l'obj<strong>et</strong> lui-même, quelle que soit la machine virtuelle dans<br />
laquelle il réside,<br />
• Les méthodes distantes provoquent des exceptions supplémentaires : les<br />
clients doivent traiter des exceptions liées au caractère distribué des<br />
méthodes qu'ils invoquent,<br />
• Le bytecode n'est transmis à la JVM qu'au moment de son utilisation.<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
page 22
Comment trouver les obj<strong>et</strong>s<br />
RMI Registry<br />
• Les clients utilisent un service de nommage – RMI<br />
Registry (rmiregistry), afin de trouver les<br />
références des obj<strong>et</strong>s distants<br />
• RMI Registry se situe à une adresse bien connue<br />
(machine <strong>et</strong> port)<br />
• Les obj<strong>et</strong>s distants doivent être enregistrés avec RMI<br />
Registry afin de pouvoir être trouvés <strong>et</strong> appelés<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
23
Appel distant<br />
• Etapes de connexion entre un client <strong>et</strong> un serveur<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
24
Fonctions RMI<br />
RMI assure les fonctions de localisation (1), communication (2) <strong>et</strong> de<br />
chargement du bytecode (3)<br />
• 1- Localisation des obj<strong>et</strong>s distants<br />
• Le serveur enregistre les obj<strong>et</strong>s qu'il exporte auprès de rmiregistry en utilisant<br />
bind()<br />
• Le client trouve des références sur ces obj<strong>et</strong>s exportées <strong>et</strong> récupère les stubs<br />
correspondants en donnant le nom des obj<strong>et</strong>s correspondants lors de l'appel à<br />
lookup()<br />
• 2- Communication transparente grâce au protocole RMI<br />
• 3- Téléchargement de code transparent grâce au protocole RMI à partir<br />
d’un URL donné (ex : utilisation de serveurs Web, Ftp, …)<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
page 25
Compilation Java vs Java + RMI<br />
• Le cas réparti nécessite la génération d’éléments de code supplémentaires<br />
: codage/décodage des requêtes, gestion des tables de nommages,<br />
correspondance requêtes/code utilisateur<br />
• La chaîne de compilation est étendue pour générer le code<br />
supplémentaire, qui va scruter le bytecode Java, <strong>et</strong> rechercher les<br />
éléments utiles (implantant les interfaces remote, serializable, …)<br />
.java<br />
.class<br />
rmic<br />
*_Stub.class<br />
*_Skel.class<br />
Application<br />
prête à être déployée<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy page 26
mic<br />
• Une fois qu'on a écrit une classe qui implémente les interfaces distantes,<br />
on crée le stub <strong>et</strong> le squel<strong>et</strong>te correspondants grâce à rmic :<br />
• Ces deux classes sont rangées dans des fichiers dont les noms sont créés par<br />
ajout de _Stub au nom de la classe pour la souche (stub), <strong>et</strong> _Skel pour le<br />
squel<strong>et</strong>te (skel<strong>et</strong>on)<br />
• Notes<br />
• L'option -keepgenerated conserve les sources des stub <strong>et</strong> squel<strong>et</strong>te<br />
• Object contient une méthode g<strong>et</strong>Class() qui donne la classe de l'obj<strong>et</strong> : en<br />
ajoutant les suffixes adéquats, on obtient les noms du stub <strong>et</strong> du squel<strong>et</strong>te<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
page 27
Java RMI<br />
1 er exemple<br />
page 28<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy
Exemple de base<br />
• Soient les fichiers : Hello.java, HelloServeur.java du côté serveur, <strong>et</strong><br />
HelloClient.java du côté client.<br />
• Contenu de Hello.java : l'interface (ce que « voit » le client):<br />
public interface Hello extends java.rmi.Remote {<br />
}<br />
String lireMessage() throws java.rmi.RemoteException;<br />
• Remote signifie que les méthodes de c<strong>et</strong> obj<strong>et</strong> Hello doivent être appelables<br />
depuis une JVM autre que la JVM locale.<br />
• HelloServeur.java implémente c<strong>et</strong>te interface :<br />
public class HelloServeur extends UnicastRemoteObject<br />
implements Hello<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy page 29
Exemple : canevas du serveur<br />
// Creation de l'obj<strong>et</strong> qui va <strong>et</strong>re invoque par les clients<br />
HelloServeur monServeur = new HelloServeur();<br />
// On enregistre le service auprès de rmiregistry<br />
//(args[0] donne le port sur lequel écoute le rmiregistry)<br />
myHostname machine = new myHostname();<br />
String nomService = "//" + machine.QualifiedHost()<br />
+ ":" + args[0] +"/HelloServeur";<br />
Naming.rebind(nomService, monServeur);<br />
• Après la compilation du serveur:<br />
• pour avoir le stub (HelloServeur_Stub.class) destiné aux clients, <strong>et</strong><br />
• le squel<strong>et</strong>te (HelloServeur_Skel.class),<br />
• il faut faire : rmic HelloServeur<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy page 30
Exemple de base: canevas du client<br />
• Voici comment invoquer une méthode sur l'obj<strong>et</strong> distant :<br />
// Donner le nom du service demandé<br />
String nomService = "//" + machine + ":"<br />
+ portRmiregistry + "/HelloServeur";<br />
Hello obj = (Hello)Naming.lookup(nomService);<br />
// On peut maintenant invoquer la méthode de l'obj<strong>et</strong><br />
// qui est hébergé par le serveur<br />
message = obj.lireMessage();<br />
• On rappelle l'interface :<br />
public interface Hello extends java.rmi.Remote{<br />
String lireMessage() throws java.rmi.RemoteException;<br />
}<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy page 31
Exemple : exécution<br />
• En étant toujours dans le même répertoire :<br />
• Lancer rmiregistry en arrière plan,<br />
• Lancer le serveur sur la même machine () que celle<br />
où tourne rmiregistry,<br />
• Lancer le client sur une machine quelconque, mais en étant dans<br />
le même répertoire pour r<strong>et</strong>rouver les stubs :<br />
• java HelloClient <br />
• Le partage du bytecode (pour les stubs) est assuré par NFS, puisque le<br />
client <strong>et</strong> le serveur, même s'ils ne sont pas sur la même machine,<br />
partagent le même système de fichiers.<br />
• Dans le cas général, il faut faire transiter les stubs par un serveur HTTP,<br />
FTP, ...<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy page 32
Synthèse<br />
• Côté serveur<br />
• Ecrire :<br />
• Lancer :<br />
• Côté Client<br />
• Les interfaces "prototypant" les méthodes distantes (extends<br />
java.rmi.Remote)<br />
• Les obj<strong>et</strong>s qui les implémentent<br />
• 1- rmic : création du stub <strong>et</strong> du squel<strong>et</strong>te à partir des fichiers .class<br />
des implémentations,<br />
• 2- rmiregistry : l'enregistrement des méthodes distantes sera fait lors<br />
de l'appel à bind<br />
• Rendre accessibles par un serveur Web les obj<strong>et</strong>s à télécharger<br />
(stubs, bytecode),<br />
• L'appel à lookup() passera un stub au client<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy page 33
Déploiement de l’application<br />
• Pour lancer un serveur :<br />
java -Djava.rmi.server.codebase=http://perso.enst.fr/~$USER/tp<br />
-Djava.rmi.server.hostname=$HOSTNAME<br />
-Djava.security.policy=java.policy HelloServeur $*<br />
• -server.codebase donne le nom du serveur web d'où les stubs seront téléchargés,<br />
• -server.hostname donne le nom de la machine où se trouve le serveur<br />
• -java.policy donne les droits d'accès qui seront vérifiés par le security manager -<br />
voici le contenu de ce fichier :<br />
grant {<br />
};<br />
permission java.n<strong>et</strong>.Sock<strong>et</strong>Permission "*:1024-65535", "connect,accept";<br />
permission java.n<strong>et</strong>.Sock<strong>et</strong>Permission "*:80", "connect";<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy page 34
Java RMI<br />
Agent distribué <strong>et</strong> RMI<br />
page 35<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy
Exemple: agent mobile<br />
• Un "client" voulant ach<strong>et</strong>er un produit va créer un agent au lieu d'interroger<br />
lui-même tous les sites détenteurs de magasins vendant le produit.<br />
• L'agent donnera au "client" le nom du site qui propose le meilleur prix.<br />
• Mise en œuvre :<br />
• Le client va lancer sa demande depuis un site appelé Initiateur.<br />
• Il initialise un tableau de sites à parcourir, puis<br />
• Il invoque à distance sur le premier site la méthode migre(), à laquelle il a<br />
passé l'agent en argument.<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
page 36
Scénario<br />
• Un "client" (Initiateur) va envoyer un Agent interroger successivement<br />
plusieurs serveurs (Hôtes)<br />
• Chaque Hôte prendra successivement le rôle de serveur <strong>et</strong> de client<br />
• Le site Initiateur démarre (<strong>et</strong> termine) le processus<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
page 37
Transfert de bytecode<br />
• Remarquez les différents obj<strong>et</strong>s téléchargés :<br />
• Le Stub (de Hôte <strong>et</strong> d’Initiateur) qui perm<strong>et</strong> l'exécution distante de la<br />
méthode migre<br />
• L‘Agent – transmis en paramètre de la méthode migre<br />
NOTE: il ne faut pas<br />
confondre l’envoi de l’instance<br />
agent (en paramètre de la<br />
méthode migre) avec le<br />
transfert du bytecode de la<br />
classe Agent<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
38
Récapitulatif du fonctionnement<br />
• La liste des Sites à parcourir se trouve dans l’agent<br />
• Le Site Initiateur appelle le premier Site Hôte<br />
• Chaque Site Hôte appelle le prochain Site Hôte (en suivant la liste des Site de l’Agent)<br />
• Le dernier Site Hôte appelle l’Initiateur<br />
• L’agent est transmis en paramètre de chaque appel distant – migre( agent )<br />
• La méthode migre de l’Initiateur est particulière - elle demande d'afficher les résultats obtenus<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
39
Descriptif des transferts de l’agent<br />
• Observez ci-dessous le circuit parcouru par l’agent :<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
40
Schéma des transferts de bytecode<br />
- codebase local -<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
41
Résumé des transferts de bytecode<br />
- codebase sur serveur http -<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
42
Le serveur<br />
• Le serveur exécute la fonction migre pour le client :<br />
• il récupère alors le code de l'agent.<br />
• il le fait exécuter par un thread qui appelle lui-même migre sur le site suivant :<br />
• Voici l'interface fournie par le serveur (Hote.java) :<br />
import java.rmi.Remote;<br />
public interface Hote extends Remote {<br />
void migre(Agent a) throws RemoteException;<br />
• Le code d'Agent n'est pas présent lors de l'écriture de ce serveur<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
page 43
Le serveur<br />
• Implémentation de l'interface (Hote_implem.java) :<br />
• La méthode migre invoquée à distance crée un thread - elle rend donc la main sans attendre la fin<br />
du traitement de l'agent (exécution puis migration).<br />
public class Hote_implem<br />
extends UnicastRemoteObject implements Hote{<br />
public Hote_implem(String fichier) throws RemoteException{<br />
super();<br />
}<br />
}<br />
public void migre(Agent a){<br />
threadAgent monThread = new threadAgent(a, monMagasin);<br />
monThread.start();<br />
}<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
page 44
L’Agent<br />
• Agent.java est l'interface pour les agents.<br />
• L'obj<strong>et</strong> sera implémenté par le "client" (Initiateur).<br />
import java.io.Serializable;<br />
public interface Agent extends Serializable {<br />
}<br />
// Traitement effectue par l'agent sur chaque hote<br />
void traitement();<br />
// Affiche le resultat des traitements : effectue par<br />
// l'agent lorsqu'il revient sur le site initiateur<br />
void afficheResultat();<br />
// Renvoie le nom de l'hote suivant a visiter par l'agent<br />
String hoteSuivant();<br />
• Serializable indique que les paramètres utilisés seront sérialisés <strong>et</strong> normalisés lors<br />
de l'appel distant (marshalling).<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
page 45
Le thread qui gère l’agent<br />
• ThreadAgent est le support système offert par un Hôte pour traiter un agent :<br />
c<strong>et</strong>te classe définit le thread qui va être lancé chaque fois qu'un agent arrive sur<br />
un site.<br />
class ThreadAgent extends Thread<br />
public void run() {<br />
}<br />
}<br />
// On effectue ici le traitement demandé par l'agent<br />
// ...<br />
// On fait ensuite migrer l'agent vers l'hote suivant<br />
Hote hote = (Hote) Naming.lookup(leSuivant);<br />
hote.migre(monAgent);<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
page 46
L’Initiateur<br />
• Implémentation de l’Initiateur, c'est à dire du site "client" qui crée <strong>et</strong><br />
lance l‘agent vers les différents serveurs.<br />
• La méthode migre est ici particulière : elle ne déclenche pas l'exécution de<br />
l'agent mais lui demande d'afficher les résultats obtenus.<br />
public class Initiateur extends UnicastRemoteObject<br />
implements Hote {<br />
}<br />
public void migre(Agent a) {<br />
a.afficheResultat();<br />
}<br />
public static void main(String args[]) {<br />
AgentIngredient agent = new AgentIngredient();<br />
hote.migre(agent);<br />
}<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
page 47
Initiateur<br />
• Voici la commande pour lancer l'initiateur :<br />
java<br />
-Djava.rmi.server.codebase=http://perso.enst.fr/~$USER/tprmi<br />
-Djava.rmi.server.hostname=$HOSTNAME<br />
-Djava.security.policy=java.policy<br />
Initiateur $*<br />
• server.codebase donne le nom du serveur web d'où l'agent sera téléchargé,<br />
• server.hostname donne le nom de la machine où se trouve l‘Initiateur<br />
• le fichier java.policy donne les droits d'accès qui seront vérifiés par le security<br />
manager<br />
A. Diaconescu, L. Paut<strong>et</strong> & B. Dupouy<br />
page 48