Introduction Java Naming and Directory Interface Gaël Thomas gael.thomas@lip6.fr Université Pierre et Marie Curie Master Informatique M2 Spécialité SAR Java Naming and Directory Interface (JNDI) Java Standard Edition API de connexion à des services d annuaires et de résolution de noms RMI Registry (RMI), CosNaming (Corba), LDAP, NIS, File System, DNS!!Uniformise l accès à ces annuaires dans une seule API!!Utilisation simultanée et transparente de ces annuaires Service de résolution de noms Associe des noms à des entités + recherche à partir du nom Service d annuaire Associe des attributs et des noms aux entités + recherche à partir des deux 2008-2009 Master SAR - M2 MDOC - Introduction 2 Introduction Exemples d annuaire Client léger : navigateur Web HTTP Serveur WEB JEE Exemple de service de résolution de noms : RMIRegistry!!API définie en Java!!Associe des noms plats à des objets RMI Rappel : objet RMI = objet Serveur, implémente l interface Remote Service Nommage : JNDI Client lourd Conteneur EJB Conteneur WEB Service de transport : IIOP, RMI ou autre Cache Conteneur EJB Service Transaction: JTA/JTX Service BD : JDBC Base De Donnée Lancer le service de résolution de noms :!!shell$ rmiregistry & Se connecter au service de résolution de noms en Java!!Registry LocateRegistry.getRegistry(String host, int port); 2008-2009 Master SAR - M2 MDOC - Introduction 3 2008-2009 Master SAR - M2 MDOC - Introduction 4
Exemples d annuaire Exemple de service de résolution de noms : RMIRegistry Utiliser le RMI Registry!!void bind(string name, Remote obj);!!void rebind(string name, Remote obj);!!string[] list();!!remote lookup(string name); Exemples d annuaire Exemple de service de résolution de noms : le système de fichiers!! API définie par le système d exploitation!! Associe des noms hiérarchiques à des objets fichiers Notion de répertoire :! Entité contenant des noms! Un répertoire possède un nom dans un autre répertoire Utiliser le système de fichier sous linux!! ls (list), rm (remove), touch/redirection (bind), mv (move) / etc bin passwd conf.d ls 2008-2009 Master SAR - M2 MDOC - Introduction 5 2008-2009 Master SAR - M2 MDOC - Introduction 6 Exemples d annuaire Exemple de service d annuaire : LDAP!! Associe des propriétés (clé=valeur) à des entités!! Chaque entité possède une classe (Person etc..) définie dans un schéma!! Structure hiérarchique, appelée DIT (Directory Information Tree)!! Chaque nœud de l arbre est une entité qui possède une propriété appelée RDN (Relative Distinguished Name) unique pour la classe Un nœud est identifié par son DN (Distinguished Name) constitué de la liste (inverse) des RDN jusqu à la racine ou=computer dc=fr dc=inria uid=anne ou=people uid=igor dn: dc=fr dn: dc=inria, dc=fr dn: ou=people, dc=inria, dc=fr dn: uid=igor, ou=people, dc=inria, dc=fr Exemples d annuaire Exemple de service d annuaire : LDAP!!Recherche : dans un sous-arbre (à partir d un DN)!!Scope : définit la profondeur de la recherche! scope=sub : dans tout le sous-arbre! scope=one : uniquement parmi les fils! scope=base : uniquement sur notre propre nœud (utile pour consulter les autres attributs d un nœud)!!recherche à l aide de filtre Exemples :! (user=bob) : cherche Bob! (&(user=b*)(objectclass=person)) : cherche une personne dont le nom commence par B! (&(age>22)(age<33)(objectclass=person)) : cherche les personne dont l âge est compris entre 22 et 33 Un annuaire LDAP est une BD hiérarchique 2008-2009 Master SAR - M2 MDOC - Introduction 7 2008-2009 Master SAR - M2 MDOC - Introduction 8
Architecture de JNDI Architecture de JNDI Architecture de JNDI JNDI API : api d utilisation de services de nommage javax.naming.*, javax.naming.directory.*, javax.naming.ldap.*, javax.naming.event.* Naming Manager : correspondance entre l API JNDI et les fournisseurs de services JNDI SPI : api interne des fournisseurs de services javax.naming.spi.* 2008-2009 Master SAR - M2 MDOC - Introduction 9 2008-2009 Master SAR - M2 MDOC - Introduction 10 Architecture de JNDI JNDI : système hiérarchique de résolution de noms et annuaire!!api d accès à des annuaires avec des fournisseurs d annuaires!!api d accès à des services de résolution de noms sinon (API d accès à un annuaire hérite de l API de résolution de noms) Différences principales entre les deux API!!Annuaire : recherche par nom ou par filtre!!service résolution nom : recherche par nom uniquement Étude dans le suite : le service de résolution de nom uniquement!!api pour les annuaires : voir la JavaDoc javax.naming.directory!!notions correspondent à celles de LDAP Architecture de JNDI Hiérarchie de contexte!!un contexte est un répertoire de noms (répertoire dans les fs, NamingContext Corba, nom de domaine DNS )!!Contient des associations <nom, objet>!!peut contenir des sous-contextes (association <nom, Context>)!!N existe que si le fournisseur de service l offre (pas le cas de RMIRegistry) InitialContext!!Contexte racine dans JNDI!!Obligatoire pour toute recherche!!construit avec new InitialContext() ou new InitialContext(Hashtable env) Possibilité de passer des paramètres au contexte initial via! Propriété (jndi.properties)! Table de hash env 2008-2009 Master SAR - M2 MDOC - Introduction 11 2008-2009 Master SAR - M2 MDOC - Introduction 12
Utilisation de JNDI Les deux paramètres de base du contexte initial!!initial_context_factory = "java.naming.factory.initial" Classe du fournisseur de service du contexte initial (Attention : cette classe doit être dans le CLASSPATH)!!PROVIDER_URL = "java.naming.provider.url» Paramètres passé au fournisseur, en général URL du service Exemple Properties props = Properties(); props.put(initial_context_factory, "com.sun.jndi.registry.registrycontextfactory"); props.put(provider_url, "rmi://localhost:1099"); Context ic = new InitialContext(props); Utilisation de JNDI Extrait de l API de Context!!void bind(string name, Object obj): associe l objet obj au nom name (chemin complet, tous les contexte intermédiaires doivent exister)!!namingenumeration<binding> listbinding(string name): renvoie la liste des associations possédant le nom name (1 niveau)!!object lookup(string name): Renvoie l objet ayant pour nom name (dans le sous-arbre)!!void rebind(string name, Object obj): Ré-associe l objet obj au nom name!!void unbind(string name): Détruit l association ayant pour nom name!!context createsubcontext(string name): Crée un sous-contexte ayant pour nom name (préférable à bind) 2008-2009 Master SAR - M2 MDOC - Introduction 13 2008-2009 Master SAR - M2 MDOC - Introduction 14 Utilisation de JNDI Exemple avec le service de résolution de noms RMI public interface Hello { void sayhello(); public HelloImpl implements Hello { implem Côté serveur Context ic = new InitialContext(props); Remote obj = new HelloImpl(); UnicastRemoteObject.exportObject(obj, 0); ic.rebind("mon-serveur", obj); Problème avec les Stateful Bean: L usine à objet A chaque client son Bean!!! ic.lookup("test@remote") renvoie un nouveau Bean à chaque appel Solution : enregistrer des javax.naming.reference!! Interception de la recherche Côté client Context ic = new InitialContext(props); Hello server = (Hello)ic.lookup("mon-serveur"); server.sayhello(); 2008-2009 Master SAR - M2 MDOC - Introduction 15 2008-2009 Master SAR - M2 MDOC - Introduction 16
Exemple : l usine MaFactory L usine à objet Exemple : l enregistrement L usine à objet public MaFactory extends ObjectFactory { public Object getobjectinstance(object obj, Name name, Context namectx, Hashtable environment) { String cname = name.get(0); // nom de l objet Class cl = Class.forName(name); // charge la classe return cl.newinstance(); interface Cinema { public CinemaImpl implements Cinema { // (class de l objet, class de l usine, classpath de l usine) Reference ref = new Reference( Cinema.class.getName(), MaFactory.class.getName(), null); ic.bind("cinemaimpl", ref); 2008-2009 Master SAR - M2 MDOC - Introduction 17 2008-2009 Master SAR - M2 MDOC - Introduction 18 Exemple : la recherche L usine à objet URL JNDI ContextInitial : associé à un unique fournisseur ic.lookup("cinemabean"); lookup Valeur retournée new CinemaBean getobjectinstance "CinemaBean" ref instance de MyFactory car Reference rmiregistry Problème : Utiliser simultanément plusieurs fournisseurs de nommages Solution : Les URL JNDI!!Définissent des protocoles!!associe des protocoles avec des fournisseurs "rmi://localhost:1099/mon-serveur", "iiop://susanoo.lip6.fr/un-autre-serveur" 2008-2009 Master SAR - M2 MDOC - Introduction 19 2008-2009 Master SAR - M2 MDOC - Introduction 20
URL JNDI URL RMI : accès direct à un service de résolution de noms URL = schema:partie-specific-au-protocole!!le fournisseur correspondant au schéma est automatiquement chargé!!évite de donner explicitement une classe au contexte initiale Construction de la classe correspondant au schema package_prefix.schema.schemaurlcontextfactory package_prefix = com.sun.jndi.url par défaut URL JNDI Exemple : InitialContext ic = new InitialContext(); Hello sever = (Hello)ic.lookup("rmi://localhost:1099/mon-server"); //! équivalent à // (new com.sun.jndi.url.rmi.rmiurlcontextfactory()) //.getinitialcontext(props) //.lookup("mon-server"); // avec props "contient" localhost et 1099 Remarque : ici, le contexte initial ic n a pas de drivers (SPI) associé 2008-2009 Master SAR - M2 MDOC - Introduction 21 2008-2009 Master SAR - M2 MDOC - Introduction 22 URL JNDI Définition de nouvelles URL JNDI!!Paramètre du contexte initial (propriété)!!context.url_pkg_prefix = "java.naming.factory.url.pkgs» Exemple : props.put(url_pkg_prefix, "org.wiz:com.bubble"); Cherche les usines à fournisseur d annuaire en essayant de charger les classes org.wiz.schema.schemaurlcontextfactory puis com.bubble.schema.schemaurlcontextfactory puis com.sun.jndi.url.schema.schemaurlcontextfactory Exemple : URL JNDI InitialContext ic = new InitialContext(props); ic.lookup("java:comp/env/ejb/cinema"); // charge com.bubble.java.javaurlcontextfactory // délègue la recherche de comp/env/ejb/cinema à // cette usine à fournisseur d annuaire 2008-2009 Master SAR - M2 MDOC - Introduction 23 2008-2009 Master SAR - M2 MDOC - Introduction 24
JNDI et Java Enterprise Edition EJB Test Nommage global Client Lourd Deux espaces de nommage pour chaque composant (Web ou EJB)!!Espace de nommage global (new InitialContext()) Service de nommage classique, service peut être distant!!espace de nommage local sous le schéma d URL java: Convention : les noms importés sont dans java:comp/env Réécriture des noms, service forcément local Principe :!!Un composant utilise les noms locaux!!le descripteur de déploiement importe les noms globaux! Le code est indépendant des noms globaux Nommage local Nommage local comp/ env/ Cinema comp/ env/ Cinema MaServlet Référence Lien Lien Test@Remote Cinema@Remote Lien Référence Utilisation directe comp/ env/ Test EJB Cinema Nommage local 2008-2009 Master SAR - M2 MDOC - Introduction 25 2008-2009 Master SAR - M2 MDOC - Introduction 26 Principe du nommage avec les annotations :!!name : le nom local!!mappedname : le nom global (donc, à éviter! Sauf pour clients lourds ) Exemple 1 : @Stateful(name= "Test", mappedname="test@remote") @Remote(Test.class) Par défaut, public class TestBean implements Test { name=nom de l interface @EJB(name="Cinema") de l entité en question Cinema cinema; (sans le package) les deux name peuvent êtres omis Exemple 1 en utilisant les paramètres par défaut :!!Fichier TestBean.java @Stateful(mappedName="Test@Remote") public class TestBean implements Test { @EJB Cinema cinema;!!fichier CinemaBean.java @Stateless public class CinemaBean implements Cinema { Tous les noms locaux des beans sont exportés dans l unité de déploiement (ici, Cinema est packagé dans le même Bean que Test) 2008-2009 Master SAR - M2 MDOC - Introduction 27 2008-2009 Master SAR - M2 MDOC - Introduction 28
Exemple 2 : @Resource(name="rigolo", mappedname="topic_rigolo") Topic topic; @Resource(name="factory", mappedname="jtcf") TopicConnectionFactory factory; Les noms dans le services globales sont donc!! "topic_rigolo" pour le topic!!"jtcf" pour l usine Intérêt du nom local : Pour modifier le lien entre nom global et nom local dans le fichier de déploiement EJB : importation de noms externes et modification des liaisons Ajouter un fichier ejb-jar.xml <ejb-jar> <enterprise-beans> <session> <ejb-name>autrebean</ejb-name> <!-- insérer ici les importations --> </session> </enterprise-beans> </ejb-jar> 2008-2009 Master SAR - M2 MDOC - Introduction 29 2008-2009 Master SAR - M2 MDOC - Introduction 30 Importation d un EJB Test dans un EJB AutreBean <ejb-name>autrebean</ejb-name> paramètre name de @EJB <ejb-ref> <ejb-ref-name>test</ejb-ref-name> <remote>mdoc.ejbsample.test</remote> <mapped-name>test@remote</mapped-name> <injection-target> nom global du Bean Test <injection-target-class> mdoc.autrebean</injection-target-class> <injection-target-name> champs @EJB de AutreBean champsejb</injection-target-name> </injection-target> </ejb-ref> class AutreBean { @EJB(name="Test") champsejb; Importation d une ressource dans un EJB AutreBean <ejb-name>autrebean</ejb-name> paramètre name de @Resource <resource-ref> <res-ref-name>monitor</res-ref-name> <mapped-name>monitoring_topic</mapped-name> <injection-target> nom global du topic <injection-target-class> mdoc.autrebean</injection-target-class> <injection-target-name> champs @Resource de AutreBean topic</injection-target-name> </injection-target> </resource-ref> class AutreBean { @Resource(name="monitor") topic; 2008-2009 Master SAR - M2 MDOC - Introduction 31 2008-2009 Master SAR - M2 MDOC - Introduction 32
Web : importation de noms externes et modification des liaisons 1 - Enrichir le fichier web.xml correspond à java:comp/env/test <ejb-ref> dans le composant Web <ejb-ref-name>test</ejb-ref-name> <ejb-ref-type>session</ejb-ref-type> <home></home> <remote>mdoc.ejbsample.test</remote> </ejb-ref> <resource-ref> <res-ref-name>monitor</res-ref-name> <res-type>javax.jmx.topic</res-type> <res-auth>container</res-auth> </resource-ref> correspond à java:comp/env/monitor dans le composant Web Web : importation de noms externes et modification des liaisons 2 - Définir le fichier jonas-web.xml <jonas-web-app> <jonas-ejb-ref> Nom local <ejb-ref-name>test</ejb-ref-name> <jndi-name>test@remote</jndi-name> </jonas-ejb-ref> Nom global <jonas-resource> Nom local <res-ref-name>monitor</res-ref-name> <jndi-name>monitoring_topic</jndi-name> </jonas-resource> Nom global </jonas-web-app> 2008-2009 Master SAR - M2 MDOC - Introduction 33 2008-2009 Master SAR - M2 MDOC - Introduction 34 Web : importation de noms externes et modification des liaisons Utilisation : void doget(httpservletrequest i, HttpServletResponse o) { Test test = (Test)(new InitialContext()). lookup("java:comp/env/test"); Topic topic = (Topic)(new InitialContext()). lookup("java:comp/env/monitor"); Ou class MaServlet extends HttpServlet { @EJB(name="Test") Test test; @Resource(name="monitor") Topic topic; Nommage et répartition!!version centralisée : deux conteneurs centralisés sur deux machines Conteneur 1 sur Machine1 Service de nommage 1 sur Machine 1!!Version distribuée : un service de nommage commun sur une autre machine Conteneur 1 sur Machine1 Service de nommage sur Machine 3 Conteneur 2 sur Machine2 Service de nommage 2 sur Machine 2 Conteneur 2 sur Machine2 2008-2009 Master SAR - M2 MDOC - Introduction 35 2008-2009 Master SAR - M2 MDOC - Introduction 36
Nommage et répartition!!version tolérante aux fautes et/ou répartition de charge Conteneur 1 sur M1 Proxy de répartition sur M1 Tolérance aux pannes Service de nommage répliqué 1 sur M3 synchronisation Conteneur 2 sur M2 Proxy de répartition sur M2 Service de nommage répliqué 2 sur M4 Conclusion JNDI : masque l hétérogénéité des services d annuaires!!une API pour de multiples services!!mais : possibilité limitées par le service! Pas d arbre avec JNDI si service RMIRegistry! Pas de lookup("*t*") avec RMIRegistry Notion d URL JNDI : accès simultané à plusieurs services d annuaire!!mais ne masque pas la localisation du service d annuaire!!mais ne masque pas le type du service d annuaire JNDI dans JEE!!Le conteneur à composant prend en charge l accès aux service de nommage!!masquage des noms réels via le schéma d URL java: + fichier déploiement!!construction avancée distribuée pour tolérance aux pannes/répartition charge 2008-2009 Master SAR - M2 MDOC - Introduction 37 2008-2009 Master SAR - M2 MDOC - Introduction 38