17.1 | Programmierung mit einem Namensdienst |
< Jede JNDI-Abfrage beginnt zunächst mit dem InitialContext. Dieser stellt den Einstiegspunkt dar, unter dem man Objekte suchen und ablegen kann. Neben dem Klassennamen des Providers wird die URL zum Einstiegspunkt angegeben.
In dem folgenden Beispiel möchten wir die Windows-Registry abfragen.
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.cogentlogic.jndi.winreg.WinregInitContextFactory");
env.put(Context.PROVIDER_URL,
"winreg://localhost/HKEY_LOCAL_MACHINE\\SOFTWARE");
InitialContext initctx = new InitialContext(env);
// Subkontext auf den JDK-Ast in der Registry
Context jdkContext = (Context) initctx.lookup(
"JavaSoft\\Java Development Kit");
Ausgehend von dem InitialContext hat der Programmierer nun verschiedene Möglichkeiten, wobei die wichtigsten Operationen im Folgenden aufgelistet sind:
- bind()
Über diese Methode werden die Objekte unter einem Namen im Context abgelegt. Dieser Vorgang wird als »Binden« bezeichnet. Dem Benutzer stehen hierbei zwei Methoden zur Verfügung: Während die Methode bind() nur neue Verknüpfungen erstellt, überschreibt ein rebind() ggf. die alte Bindung.jdkContext.rebind("CurrentVersion", "1.4");- rename()
Die Methode rename() ändert den Namen, unter dem ein Objekt gespeichert ist.jdkContext.rename("CurrentVersion", "FormerVersion");- unbind()
Diese Methode dient dazu, eine Bindung zu löschen.jdkContext.bind("tobedeleted", "Test"); jdkContext.unbind("tobedeleted");- createSubcontext()
Durch diese Methode kann der Programmierer neue Subkontexte anlegen.jdkContext.createSubcontext("Neues Verzeichnis");- destroySubcontext()
Soll ein Kontext entfernt werden, wird diese Methode benutzt.jdkContext.destroySubcontext("Neues Verzeichnis");- lookup()
Mithilfe dieser Methode können Objekte oder Subkontexte anhand eines Namens relativ zum Context gelesen werden.System.out.println( jdkContext.lookup("CurrentVersion"));- list()
Diese Methode zeigt alle gebundenen Objekte des Context an. Dies können Subkontexte oder Objekte sein. Während die Methode list() nur den Namen und die Datenklasse eines Objektes liefert, bietet die Methode listBindings() Zugriff auf das gebundene Objekt.// Alles auflisten NamingEnumeration enum = initctx.list(""); while(enum.hasMore()) { NameClassPair ncp = (NameClassPair) enum.next(); // Einfache Ausgabe der Namen und Datenklassen System.out.println(ncp); }
Das folgende Beispiel zeigt die Abfrage des Namensdienstes RMI (Abschnitt 19.2). Das Programm startet die RMI-Registry und registriert dann dort ein Objekt, um dieses mithilfe vom JNDI abzufragen.
package de.dpunkt.jndi;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.registry.LocateRegistry;
import javax.naming.InitialContext;
import javax.naming.Context;
import java.util.Hashtable;
public class RMIRegistryExample {
public RMIRegistryExample() {}
/**
* Das Remote-Interface, welches die
* öffentlichen Methoden beinhaltet
*/
public static interface HelloInterface
extends Remote {
public String getMessage()
throws RemoteException;
}
/**
* Remote-Objekt, welches HelloInterface
* implementiert
*/
public static class HelloImpl extends UnicastRemoteObject
implements HelloInterface {
public HelloImpl() throws RemoteException {}
public String getMessage() {
return "Hello World";
}
}
public static void main (String[] args)
throws Exception {
// Registry starten
LocateRegistry.createRegistry(1099);
// Kontext setzen
Hashtable hashtable = new Hashtable(2);
hashtable.put (Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.rmi.registry.RegistryContextFactory");
hashtable.put (Context.PROVIDER_URL,
"rmi://localhost:1099");
InitialContext ictx = new InitialContext(hashtable);
// Remote-Objekt binden
ictx.bind ("HelloObj", new HelloImpl());
// Remote-Objekt durch Namen holen
HelloInterface helloObj =
(HelloInterface) ictx.lookup("HelloObj");
// Remote-Objekt abfragen
System.out.println(helloObj.getMessage());
}
}