![]() |
JNDI a History JNDI plays a role in a number of Java technologies. Three of them are as follows:
JDBC-- The Java technology for relational databases. JNDI first appeared in the JDBC 2.0 Optional Package in conjunction with the DataSource interface. A DataSource instance, as its name implies, represents a source of data, often from a database, but not always. A DataSource instance stores information about a data source, such as its name, the driver to load and use, and its location, and allows an application to obtain a connection to the data source without regard to the underlying details. The JDBC specification recommends using JNDI to store DataSource objects. JMS-- The Java technology for messaging. The JMS specification describes administered objects - objects that contain JMS configuration information and are used by JM to locate specific message queues and topics. As is the case with JDBC, the specification recommends locating JMS administered objects via JNDI. EJB-- All enterprise beans publish a home interface via JNDI. This is the single location though which clients locate a specific enterprise bean. So, if this is the case, why is JNDI so highly regarded? For one reason, JNDI promotes the notion of a centrally managed information source, which is a key requirement for enterprise applications. A centrally managed information source is easier to administer than a distributed collection of information sources. It's also simpler to clients to locate needed information if they only have to look in one place. Also, JNDI's ability to directly store Java objects allows it to integrate almost transparently into Java applications. JNDI Provider To use JNDI, you need a naming and directory service and JNDI service provider. Sun supplies several providers of common naming and directory services such as COSnaming, NIS, RMI, LDAP and more. For the sake of this course and since eDirectory supports it, I have chosen LDAP. LDAP has the advantage of being widely implemented (eDirectory) in commercial and open-source forms and also being quite easy to use. Its features are also well supported by Sun's LDAP service provider and JNDI. In addition to eDirectory, there are other options for LDAP providers. Numerous LDAP implementations are available. Many are commercial products such as eDirectory, Netscape Directory Server and IBM's Secure Way Directory. Some are packaged as a part of a larger offering (eDirectory is part of the NetWare server). If you have access to such an implementation of eDirectory or another commercial LDAP provider, then you can skip the next section on OpenLDAP, if not, then OpenLDAP may be a good solution for you. OpenLDAP OpenLDAP is a freely available implementation of LDAP that is based on University of Michigan's LDAP reference implementation. OpenLDAP is available from the OpenLDAP Foundation (http://www.openldap.org). OpenLDAP's license is referred to as an "artistic license," which means that open LDAP is free (or open source) software. Prepackaged files are available for various flavors of Linux as well as BSD Unix. Work is currently underway on a port for Windows NT. Connecting to a JNDI Context Before you can do anything with JNDI, you need an initial context. All operations are performed relative to the context or one of its subcontexts. Follow these steps to setup a context:
Hashtable hashtableEnvironment = new Hashtable();
// the service: ldap://localhost:389/
Context context = new InitialContext(hashtableEnvironment); Or for a directory: DirContext dircontext = new InitialDirContext(hashtableEnvironment); Now let's look at how applications store objects to and retrieve objects from JNDI. Dealing With Objects The ability to store Java objects is useful: object storage provides persistence and allows objects to be shared between applications or between different executions of the same application. From the standpoint of the code involved, object storage is quite easy: context.bind("name", object);
The bind() operation binds a name to a Java object. It is permissible for the bind() operation to store either a snapshot of the object or a reference to a "live" object, for example. Be aware that the bind() operation throws a NamingException if an exception occurs during the execution of the operation. Now let's take a look at the bind() operation's complement - lookup(): Object object = context.lookup("name");
The lookup() operation retrieves the object bound to the specified name. Just as with bind(), the lookup() operation throws a NamingException if an exception occurs during the execution of the operation. Storing Objects What does it mean to store an object in a JNDI naming and directory service? We have already mentioned that the exact semantics of the bind() and lookup() operations are not tightly defined; it is up to the JNDI service provider to define their semantics. According to the JNDI specification, service providers are encouraged (but not required) to support object storage in one of the following formats:
If all JNDI service providers support these standard mechanisms, Java programmers are free to develop generic solutions that work even when the underlying service provider layer changes. Each of the methods above has advantages and disadvantages. The best method will depend on the requirements of the application under development. Let's look at an example of each: Serialized Data The most obvious approach to storing an object in a directory is to store the serialized representation of an object. The only requirement is that the object's class implement the Serializable interface. When an object is serialized, its state becomes transformed into a stream of bytes. The service provider takes the stream of bytes and stores it in the directory. When a client looks up the object, the service provider reconstructs it from the stored data. The following code shows how to bind a LinkedList to an entry in a JNDI service: // create a linked list Reference Sometimes it is not appropriate or not possible to serialize an object. If the object provides a service on a network, for example, it doesn't make sense to store the state of the object itself. We are interested in the information necessary to find and communicate with the object. An example is a connection to an external resource (one outside the scope of the Java Virtual Machine) such as a database or file. It clearly doesn't make sense to try to store the database or the file itself in the JNDI service. Instead, we want to store the information necessary to reconstruct the connection. In this case the programmer should either bind a Reference instance that corresponds to the object or have the object's class implement the Referenceable interface (in which the object generates and provides a Reference instance when requested by the service provider). The Reference instance contains enough information to recreate the reference. If a reference to a file was stored, the reference contains enough information to create a File object that points to the correct file. Attributes in a Directory Context If you are using a service provider that provides directory functionality instead of only naming functionality, you can also store the object as a collection of attributes on a DirContext object (a DirContext instance differs from a Context instance in that it may have attributes). To use this method, you must create objects that implement the DirContext interface and contain the code necessary to write their internal state as an Attributes object. You must also create an object factory to reconstruct the object. This approach is useful when the object must be accessible by non0Java applications. Up next, a sample application.
|
||||||||||||||||||
![]() |
|||||||||||||||||||