JNDI: Java Naming and Directory Interface

In questo articolo vedremo cos’è un servizio di Naming ed un servizio di Directory dopodiché vedremo come è possibile accedere a questi servizi tramite la API JNDI.

Un servizio di naming (naming service) è un sistema per associare nomi a degli oggetti  e trovare degli oggetti in base al loro nome. Molti programmi che usiamo quotidianamente utilizzano dei nomi per individuare degli oggetti come ad esempio la posta elettronica: dobbiamo fornire il nome del destinatario affinchè un messaggio possa essere inviato e ricevuto da esso. Oppure quando vogliamo accedere ad un file dobbiamo sempre fornire un nome per potervi accedere. Una funzionalità di un naming service è quella di mappare nomi user-friendly (facili soprattutto da ricordare) con indirizzi, identificatori o veri e propri oggetti usati dai programmi. Ad esempio il DNS mappa le URL di una macchina (www.appuntisoftware.it) su indirizzi IP (ad esempio 192.168.1.2).

Dunque per ottenere un oggetto dato un nome (operazione che viene chiamata di lookup) bisogna fornire il nome, sarà poi il naming system a determinare quale sintassi il nome deve seguire, questa regola di sintassi prende il nome di naming convention. Ad esempio la naming convention per il DNS prevede che il richiamo dei componenti presenti nel nome DNS avviene con ordine da destra verso sinistra, delimitati dal carattere punto (“.”). Quindi un nome del tipo www.appuntisoftware.it identifica una entry con nome www relativa ad una entry DNS appuntisoftware.it e a sua volta la entry appuntisoftware.it identifica una entry con nome appuntisoftware corrispondente ad una entry di tipo it.

L’associazione di un nome con un oggetto è chiamata binding. Ad esempio un nome può essere associato (bound) ad un file. Un nome DNS è associato ad un indirizzo IP. A seconda del naming service, un oggetto può essere conservato direttamente al suo interno oppure può esserne conservato solo un puntatore (riferimento). Un sistema di naming DNS contiene un riferimento all’indirizzo IP della macchina e quindi, ovviamente, non la macchina stessa.

Un contesto (context) invece è un insieme di binding tra oggetti e nomi, all’interno dei quali esiste una propria naming convention. Un context deve fornire una operazione di risoluzione (lookup) che ritorni un oggetto dato un nome e può fornire altre operazioni quali quella di binding, unbinding di nomi e fornire una lista di binding. Un nome in un context può essere associato ad un altro context (chiamato subcontext) che ha la stessa naming convention. Ad esempio un domino DNS come it è un context. Un dominio DNS relativo ad un altro dominio DNS è un subcontext. Ad esempio nel dominio DNS appuntisoftware.it , appuntisoftware è un dominio che è un subcontext di it.

Un servizio di directory (directory service) è invece una estensione del naming service. Un directory service permette di associare un nome ad un oggetto ed inoltre permette ad un oggetto di avere degli attributi. Di conseguenza non solo si può fare il lookup di un oggetto dato il suo nome, ma anche ottenere gli attributi di un oggetto oppure di ricercare un oggetto in base ad un particolare attributo.

Un oggetto di una directory  (directory object) rappresenta  un oggetto in un ambiente di computing. Un directory object può essere una stampante, una persona, un computer o una rete. Un attributo di una stampante può essere la sua velocità, la sua risoluzione e il numero di colori. Un attributo ha un proprio identificatore (attribute identifier) ed un insieme di valori. L’identificatore è un token che identifica un attributo indipendentemente da suo valore. Ad esempio due account di un computer possono avere entrambi un attributo “mail”, dove “mail” è l’identificatore dell’attributo. L’indirizzo email vero è proprio è il valore dell’identificatore ed è diverso per ognuno dei due account.

Un esempio di directory è la Novell Directory Service (NDS) che è una directory di nomi ideata d aNovell che fornisce informazioni riguardanti i servizi di una rete, quali ad esempio i file e i servizi di stampa. Un altro esempio sono le directory LDAP che organizzano gli oggetti di una directory in una gerarchia ad albero chiamata directory information tree (DIT). All’interno della DIT, un oggetto che rappresenta una Organizzazione può contenere a sua volta degli oggetti che rappresentano delle persone.

JNDI è un insieme di API che forniscono ad applicazioni scritte in Java funzionalità di accesso a servizi di naming e servizi di directory. E’ stata definita per essere indipendente da ogni specifica implementazione di servizio di Directory e di Naming, così da permettere l’accesso ad una grande varietà di directory in un modo comune.

L’architettura di JNDI consiste in un API e in un Service Provider Interface (SPI). Le applicazioni Java usano le API JNDI per accedere ai servizi di Naming e di Directory. La SPI invece consente ad una varietà di servizi di naming e di directory di essere collegati in modo del tutto trasparente, permettendo alle applicazioni Java di accedere ai loro servizi tramite JNDI.

Architettura di JNDI

Le API JNDI sono incluse nella JDK a partire dalla versione 1.3 e per poter essere utilizzate hanno bisogno di uno o più service provider a seconda di quale vogliamo utilizzare. Tre di questi service provider sono però già inclusi nella JDK, e permettono l’accesso a questi servizi di Naming e Direcotry:

  • LDAP;
  • CORBA e COS;
  • RMI.

Altri Service Provider possono essere scaricati da questo indirizzo:

http://java.sun.com/products/jndi/serviceproviders.html

JNDI è diviso in cinque packages:

  • javax.naming
  • javax.naming.directory
  • javax.naming.event
  • javax.naming.ldap
  • javax.naming.spi

Il package javax.naming contiene classi ed interfacce per accedere ai servizi di naming, in particolare viene definita l’interfaccia Context che rappresenta la via principale per le operazioni di lookup, binding e unbinding, rename degli oggetti e creazione e distruzione dei subcontext. Tutti questi metodi hanno due overloads (cioè hanno lo stesso nome ma possono accettare un diverso parametro): uno accetta una stringa (java.lang.String) l’altro un oggetto di tipo Name, quest’ultima è una interfaccia che rappresenta un nome generico formato da una sequenza di componenti (si veda questa url: http://download.oracle.com/javase/1.3/docs/api/javax/naming/Name.html).

Viene definita inoltre la classe InitialContext che implementa l’interfaccia Context, la quale rappresenta il punto di inizio per ogni operazione che coinvolge un servizio di Naming o di Directory. Una volta ottenuta una istanza di InitialContext è possibile utilizzare il lookup degli oggetti. Per creare una tale istanza bisogna fornire al costruttore un insieme di proprietà in forma di Hashtable o una delle sue sottoclassi come Properties, ad esempio:

Hashtable env = new Hashtable();
// seleziono una service provider factory, ad esempio una SPI per il FileSystem
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContext");
// creo l' initial context
Context contxt = new InitialContext(env);

INITIAL_CONTEXT_FACTORY specifica il nome della classe Factory presente all’interno del Service Provider scelto (in questo caso un SPI del FileSystem).

Name Service Provider Factory
File System com.sun.jndi.fscontext.RefFSContextFactory
LDAP com.sun.jndi.ldap.LdapCtxFactory
RMI com.sun.jndi.rmi.registry.RegistryContextFactory
CORBA com.sun.jndi.cosnaming.CNCtxFactory
DNS com.sun.jndi.dns.DnsContextFactory

Tabella 1: Valori di esempio di Context.INITIAL_CONTEXT_FACTORY

Ottenuto l’InitialContext possiamo ottenere un oggetto tramite una operazione di lookup indicandone il nome:

Object obj = contxt.lookup(name).

Nei prossimi articoli vedremo come utilizzare le API JNDI per accedere ai servizi di Naming

1 Stella2 Stelle3 Stelle4 Stelle5 Stelle (Nessun voto ancora)
Loading...
You can leave a response, or trackback from your own site.

One Response to “JNDI: Java Naming and Directory Interface”

  1. Leonardo ha detto:

    Ciao,

    io ho caricato Jackrabbit su Glassfish, e cerco di accedervi tramite JNDI ma mi rifiuta la connessione, come faccio a cverificare che sia glassfish e non Jackrabbit?
    Mi sembra come non sia attivo RMI sul server o sia su una porta da specificare, come lo attivo? come verifico se RMI gira correttamente?

    Grazie, leonardo

    ERRORE:
    javax.naming.ServiceUnavailableException [Root exception is java.rmi.ConnectException: Connection refused to host: 192.168.80.55; nested exception is:
    java.net.ConnectException: Connection refused: connect]
    at com.sun.jndi.rmi.registry.RegistryContext.lookup(RegistryContext.java:122)
    at com.sun.jndi.rmi.registry.RegistryContext.lookup(RegistryContext.java:128)
    at javax.naming.InitialContext.lookup(InitialContext.java:417)
    at it.leo.jcr.connection.JCRConnection.getIstance(JCRConnection.java:62)
    at it.leo.jcr.connection.JCRConnection.getConnection(JCRConnection.java:87)
    at it.leo.jcr.Main.main(Main.java:22)

Leave a Reply

*