Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 67 di 68
  • livello ninja
Indice lezioni

Java Naming and Directory Interface

JNDI: interrogare il registro per recuperare un servizio
JNDI: interrogare il registro per recuperare un servizio
Link copiato negli appunti

Durante le diverse lezioni di questa guida abbiamo incontrato in molte occasioni il concetto di JNDI. Cerchiamo di capire cos'è e perché assume tanta importanza nella programmazione distribuita.

JNDI (Java Naming and Directory Interface) è il servizio di naming utilizzato per registrare in contesti distribuiti dei servizi e richiamarli utilizzando un nome mnemonico. Si tratta di un registro che mantiene in una struttura dati l'associazione tra un nome ed un servizio dell'application server.

Il suo utilizzo è fondamentale in quanto ogni richiesta di servizio (all'interno dello stesso ambiente o su una macchina remota) passa necessariamente per questo registro.

Questa peculiarità ci ha fatto più volte dire che il servizio stesso virtualizza l'ambiente di esecuzione dell'application server. È in parte vero, in quanto attraverso di esso riusciamo a recuperare i servizi presenti, ma di fatto rappresenta solo la struttura in cui i servizi vengono registrati.

La struttura dati è una struttura a directory (la reale implementazione dipende dall'application server, ma in genere è una struttura Hashtable), divisa per tipologia di servizi. Esisterà la directory in cui vengono registrati gli EJB, la directory dei Datasource, quella dei Web Services, quella delle code e via discorrendo.

L'accesso può avvenire anche da remoto, importante è che gli oggetti registrati siano oggetti remoti (interfaccia Remote). La logica di comunicazione è indipendente dal protocollo utilizzato, il che rende JNDI accessibile da diversi linguaggi di programmazione (CORBA, ad esempio). Questo è reso possibile dalla presenza di diverse implementazioni, ognuna basata sul protocollo di comunicazione di basso livello utilizzato (RMI, LDAP, CORBA, ecc).

Dal punto di vista dello sviluppatore, un servizio JNDI è realizzato dall'interfaccia javax.naming.Context, che viene esteso concretamente da InitialContext e tutte le sottoclassi che ogni application server ridefinisce in maniera proprietaria.

Properties props=new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
props.put(Context.PROVIDER_URL, "jnp://localhost:1099");
Context ctx=new InitialContext(props);

Il listato precedente serve per accedere al servizio di naming su JBoss. Per renderlo indipendente dall'implementazione, le definizioni concrete (classe e url di accesso) vengono inserite all'interno di una struttura dati Properties. Utilizzando un altro application server avremmo dovuto cambiare esclusivamente le due proprietà.

Un'altro modo utilizzato è quello di creare il file jndi.properties e inserirvi queste informazioni. A runtime, il costruttore di default InitialContext(), legge questo file (deve essere nel classpath) e recuperà le informazioni necessarie: in questo modo al cambiare delle informazioni non sarà necessario ricompilare la classe, ma solo modificare opportunamente il file.

#jndi.properties

java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory
java.naming.provider.url=t3://127.0.0.1:7001
#java.naming.security.principal=utente
#java.naming.security.credentials=password

Il listato che precede mostra il file di properties per accedere al servizio JNDI su Bea Weblogic. Questo è quello che viene fatto dall'application server, che mantiene il suddetto file. Infatti, le classi eseguite sull'application server (ejb, transazioni, web services, ecc) non devono definire le proprietà (le recuperano in automatico dal file di properties dell'application server).

L'interfaccia Context presenta semplicemente due metodi, quello di pubblicazione (utilizzato dall'application server in fase di deploy), bind(String, Object), e quello di ricerca del servizio (utilizzato dallo sviluppatore), lookup(String), che restituisce un Object (quindi ricordatevi l'operazione di cast).

..//
Context ctx=new InitialContext();
..//
ctx.bind("Servizio1", new String("ciao"));
..//
String service=(String) ctx.lookup("Servizio1");
..//

Ti consigliamo anche