RMI Remote Method Invocation L’objectif: pouvoir invoquer de manière transparente pour le programmeur une méthode sur un objet distant. Le serveur et le client ne s’exécutant pas forcement sur la même JVM (Java Virtual Machine). Avantages, inconvénients: + RMI est simple à mettre en œuvre + RMI étend le « garbage Collector » de Java + RMI permet une gestion de la sécurité élémentaire - RMI est la propriété de SUN - RMI n’est pas inter opérable (pas d’interactions facile avec des langages autres que Java) - RMI est un peu plus lent que CORBA Le serveur héberge des objets accessibles à distance. Le client possède des objets qu’ils croit locaux mais qui sont en fait sur le serveur. Client JVM Proxy Serveur JVM S oD Le proxy (représentant l’objet distant) a la même interface que l’objet distant. Scénario d’un appel distant: 1) Le client invoque une méthode sur le proxy 2) Le proxy sérialise les paramètres et le nom de la méthode 3) Requête transmise sur le réseau 4) Le squelette reçoit et désérialise la requête 5) La méthode est invoquée dans la JVM du serveur 6) Le squelette emballe, sérialise le résultat 7) Transmission sur le réseau 8) Le proxy désérialise le résultat 9) Le proxy renvoie le retour de l’invocation distante 1) Développement d’une application RMI Le déroulement typique d’un développement : - la définition de l’interface d’appel aux objets distants. L’interface définit le contrat client - serveur - la programmation d’une implémentation des méthodes des objets distants - développer le serveur qui instancie des objets accessibles à distance - développer le client qui utilise les objets distants en faisant des invocations sur ces objets Compilation / Déploiement • • • • javac –java rmic MesgImpl #création proxy/squelette rmiregistry [port] java serveur 1099 Diagramme de classes rmic –keep MessagImpl java.rmi.remote implémente java.rmi.server.UnicastRemote Message MessageImpl utilise invocation Lien réseau MessageImpl_Stub MessageImpl_Skel Client Serveur 2) Mécanisme interne : passage de paramètres Appel de méthodes : En java, les paramètres sont passés par référence, sauf pour les types primitifs qui sont passés par valeur (int, float, char…) . En RMI, lors d’un appel distant : - Les paramètres de type primitif sont passés par valeur - Les objets sérialisables (implémente java.io.Serializable) sont sérialisés lors de l’appel de méthode (passage par valeur). L’objet est envoyé du client vers le serveur. - Les objets accessibles à distance sont passés par référence. - Les autres objets provoquent l’exception java.rmi.MarshallException. Tout ceci est aussi valable concernant le retour de méthode. Différence sémantique entre l’appel de méthode classique et distante. Le programmeur doit y faire attention car il peut travailler sur des copies d’objet. 3) Mécanisme interne : obtention d’un proxy Pour obtenir un proxy : - utiliser un service de nommage (rmiregistry) qui conserve une liste d’association <URL, référence d’objets> URL : [rmi://][machineServeur[ :port]/]nomObjet - avoir appelé une méthode qui renvoie un objet distant (une référence == proxy) Exemple de transfert de proxys dans une application distribuée M1 M2 sA pC pB sB A B M3 sC C Sur M1, appel à B.méthodeD(A,C) M1 M2 pA sB pB pA sA pC A B M3 sC C 1) Instanciation de pA qui s’envoie à M2 ou bien M2 possède pA dans ses systèmes de fichiers et l’instancie 2) Appel de méthodeD → utilisation de A et C à distance 3) Retour de méthode (sB vers pB) Chargement dynamique de la classe (proxy) Les proxys peuvent être téléchargés si la classe du proxy n’est pas disponible localement. 1) La classe du proxy est cherchée dans le CLASSPATH défini dans le service de démarrage (rmiregistry) 2) La classe du proxy peut est téléchargée depuis une URL java –D java.rmi.server.codebase = URL appli 3) La classe proxy peut être téléchargée en modifiant le RMIClassLoader. Le programmeur définit la manière de rapatrier la classe du proxy manuellement 4) Service de nommage rmiregistry n’est pas la seule alternative. Fonctions disponibles dans la classe : a. « Nominy » : bind, rebind, lookup, unbind, list b. classe LocateRegistry: java.rmi.registry.LocateRegistry.createRegistry(port) 5) Sécurité en RMI Il est possible en s’appuyant sur les mécanismes de java de restreindre l’accès aux ressources locales (fichiers, réseau). Un agent de sécurité RMI Security Manager est en charge d’appliquer les stratégies de sécurité : If(System.getSecurityManager()==null){ System.setSecurityManager(new RMISecurityManager()) } - Définition de stratégie : un outil « policytool » → dans un fichier « java.policy » - On met en œuvre des stratégies avec : java –D java.security.policy = java.policyAppli - Paramétrage des connexions TCP/IP → RMISocketFactory - rmic sert à générer le squelette et le proxy à partir du code associé à l’objet distant => génération de classes proxy et squelette sur le serveur. Le client doit récupérer l’interface de l’objet distant et la classe proxy pour pouvoir fonctionner. En CORBA, le client doit uniquement connaître l’interface de l’objet distant pour pouvoir fonctionner.