MokaByte Numero  41  - Maggio 2000
L'interfaccia JNDI 
del JDK 1.2
di 
D'amore 
Salvatore
In questo articolo sara' descritta l'interfaccia JNDI di Java2, mentre nel prossimo sara' mostrato un piccolo esempio client/server per evidenziare le principali innovazioni della nuova architettura

L'evoluzione sempre piu' spinta dei modelli architetturali distribuiti (DCOM, CORBA) fa sentire con crescente insistenza l'esigenza di una comunicazione efficiente fra i moduli della stessa applicazione: Sun con l'interfaccia JNDI propone una soluzione proprietaria per la comunicazione, altamente innovativa per la sua versatilita'

Con l'interfaccia JNDI (Java Naming Directory Interface) Sun propone una struttura molto versatile per gestire la comunicazione fra moduli software: prima di descriverla, pero', e' opportuno capire quali funzioni svolgono, all'interno di un'architettura distribuita, i servizi di Naming e di Directory, e di introdurre un po' di terminologia specifica.

La funzione principale di un servizio di Naming e' quella di associare (mapping) nomi ad oggetti: in questo senso, un classico esempio puo' essere quello dei Domain Name Server (DNS) che offrono la risoluzione dei nomi su Internet, che associano ad un nome simbolico (www.qqq.com) un indirizzo IP nel formato standard (127.127.127.127).

Con il termine "naming convention" si intende la sintassi con cui si indicano gli oggetti: ad esempio, per indicare i path del file system in Unix si utilizza lo "/" (es: /usr/bin/hello.c, file hello.c situato nella directory bin, che a sua volta e' sottodirectory di usr, che si trova nella root), per i DNS si usa la "dotted notation" (la classica notazione che si usa per indicare gli URL, www.altavista.digital.com). Nel Lightweight Directory Access Protocol (LDAP) per convenzione i componenti sono ordinati da destra a sinistra, delimitati dalla virgola (","), e sono definiti da una coppia nome/valore, separati dal carattere "=": cosi' con la notazione nc=Giovanni Rossi, o=Sun, n=IT si indica un elemento LDAP nc=Giovanni Rossi relativo all'elemento o=Sun, che a sua volta e' relativo all'elemento n=IT (nome completo, organizzazione, nazione).

Un Contesto e' un insieme di associazioni nome-oggetto. Ad ogni contesto e' associata una naming convention, ed offre un sistema di risoluzione ('lookup') dei nomi, che offre il riferimento all'oggetto desiderato.

Un Naming System e' un insieme di Contesti dello stesso tipo (cioe' caratterizzati dalla stessa naming convention) ed offre un insieme di operazioni in comune: ad esempio, il DNS e' un Name System.

Un Namespace e' un insieme di nomi all'interno di un Naming System.

Un Directory Object rappresenta un oggetto in un ambiente computazionale, ed e' descritto da una serie di attributi. Gli attributi, come per le classi, identificano un oggetto all'interno di un contesto: ad esempio un 'utente' puo' essere rappresentato da un Directory Object che abbia come attributi un indirizzo di posta elettronica, un numero di telefono, un numero di fax, ...

Una Directory e' costituita da un insieme di Directory Object.

Un servizio di Directory offre la possibilita' di manipolare questi oggetti, crearli, modificarli, cancellarli, e soprattutto selezionarli in base agli attributi tramite opportuni filtri di ricerca (search filter): un'operazione possibile, ad esempio, puo' essere quella di selezionare, all'interno di una Directory contenente oggetti di tipo 'utente' tutti gli elementi che hanno un indirizzo di posta elettronica che termina con la stringa "@hotmail.com".

Fatte le dovute premesse, passiamo ora ad esaminare l'oggetto dell'articolo, ed iniziamo dall'acronimo: JNDI, Java Naming and Directory Interface.
Sun ha quindi scelto di offrire al programmatore un'interfaccia, poiché in questo modo il servizio di Naming può essere utilizzato indipendentemente dalla sua implementazione, coerentemente con la filosofia che propone Java come un linguaggio aperto, al quale tutti possono aggiungere in maniera semplice componenti.
Per capire meglio quanto affermato si osservi la figura seguente:
 
 


Figura 1

L'applicazione Java vede solamente le API della JNDI, la quale al suo interno ha una struttura a livelli, e di questi l'ultimo e' quello che caratterizza il tipo di comunicazione: la stessa interfaccia, quindi, supporta diversi protocolli di comunicazione in maniera del tutto trasparente al programmatore. Per la precisione, la versione 1.3 delle SDK di Java2 contiene le classi che implementano i seguenti protocolli:

  •  Lightweight Directory Access Protocol (LDAP)
  • CORBA services (COS) naming service
  • Java Remote Method Invocation (RMI) Registry 
mentre per la versione 1.2 bisogna scaricare le classi opportune dal sito http://java.sun.com/products/jndi, a seconda del protocollo che si desidera implementare.
Si passa ora ad esaminare la struttura delle classi di JDNI, che e' divisa in cinque package (contenuti dalla Enterprise Edition di Java2):
javax.naming
javax.naming.directory
javax.naming.event
javax.naming.ldap
javax.naming.spi
Di questi package descriveremo le classi piu' significative, trascurando, ad esempio, gli svariati tipi di eccezioni, per non perderci nei dettagli della realizzazione: ricordiamo che la maggior parte delle classi descritte in seguito sono in realta’ interfacce, poiche' da soli questi package non possono essere utilizzati, se non in combinazione con una delle possibili implementazioni (si vedra’ nell’articolo successivo come scegliere l’implementazione desiderata).

Il package naming contiene le classi Context, Name, Binding, Reference, InitialContext, NamingException
La classe Context definisce il contesto in cui si lavora, sul quale si effettuano le operazioni di lookup, bind, rename degli oggetti.
La classe Name rappresenta una maniera alternativa di definizione dei nomi degli oggetti: comunque ogni metodo che accetta come parametro il nome di un oggetto e' riscritto per poterlo accettare sia come stringa sia come elemento di classe Name. Questa funzionalità può essere utile nel caso in cui gli oggetti hanno nomi complessi, che possono anche rispecchiare una gerarchia nello spazio di naming.
Gli oggetti di classe Binding sono terne contenenti il nome dell'oggetto, il nome della classe e l'oggetto stesso: questi oggetti sono utili quando si chiede l'elenco degli oggetti pubblicati in un contesto con il metodo listBindings().
Alcuni sistemi non supportano la serializzazione Java: in questi casi JNDI offre la classe Reference per dare l'illusione al programmatore che l'oggetto memorizzato dal servizio di Naming o di Directory sia comunque un oggetto Java.
La classe InitialContext e' il punto iniziale per la creazione di oggetti JNDI: dopo aver istanziato un oggetto di questa classe, al suo interno possono essere creati oggetti e contesti.
La classe NamingException funge da root per le eccezioni generate dai moduli JNDI

Il package naming.directory contiene la classe DirContext.
La classe DirContext offre i servizi di Naming, poiche' estende l'interfacccia Context, ed in piu' offre i servizi di Directory, ovvero di gestione degli attributi degli oggetti.

Il package naming.event contiene le classi NamingEvent, NamingListener, NamespaceChangeListener e ObjectChangeListener.
La classe NamingEvent rappresenta gli eventi caratteristici di un sistema di Naming, ovvero la creazione, la modifica degli attributi o del valore, e la cancellazione degli oggetti.
Gli oggetti di classe NamingListener sono "interessati", con la stessa politica degli eventi gestita per gli oggetti grafici, agli eventi della classe NamingEvent: in particolare quelli di classe NamespaceChangeListener sono interessati agli eventi di variazione del contesto (creazione e cancellazione di oggetti), mentre gli ObjectChangeListener sono interessati agli eventi di variazione degli oggetti.
I corrispondenti eventi sono definiti dalle classi EventContext ed EventDirContext.

Il package naming.ldap contiene classi che estendono le funzioni del package naming.directory, particolarizzandole per il caso del protocollo LDAP v3 (RFC 2251).

Il package naming.spi puo' essere utilizzato dagli sviluppatori che interagiscono con provider di servizi di Naming e di Directory differenti, per incapsularli con una semplice architettura di tipo plug-in.
Tramite la classe ObiectFactory e' possibile sia importare ed utilizzare oggetti offerti da provider diversi, sia gestirli con JNDI ed esportarli nel formato richiesto dai provider esterni.

Conclusione: nel presente articolo sono state descritte le funzionalita' caratteristiche dell'interfaccia JNDI, facendo una breve carrellata delle classi piu' significative: gli "smanettoni" possono dedicarsi allo studio del tutorial indicato nella bibliografia, che presenta esempi utilizzando l'implementazione LDAP, mentre nel prossimo articolo sara' presentato un codice esemplificativo di colloquio client/server con l'implementazione RMI, confrontandolo con la comunicazione RMI e CORBA, ed evidenziandone pregi e difetti

Bibliografia
Il sito della Sun e’ una fonte insostituibile di documentazione, in particola sull’argomento si puo’ consultare il seguente tutorial:
http://java.sun.com/products/jndi/tutorial/trailmap.html
 

Mini Biografia:
Laureato a Napoli alla facolta’ Federico II in Ingegneria Informatica nel 1999, ho partecipato al master in “Internet Software Design” tenuto presso l’istituto Cefriel di Milano nello stesso anno (da maggio a dicembre): da gennaio lavoro presso la Siemens Informatica S.p.A. di Roma come Analista e System Integrator.
 

Chi volesse mettersi in contatto con la redazione può farlo scrivendo a mokainfo@mokabyte.it