WebObjects 5.2.3

Package com.webobjects.jndiadaptor

Provides an implementation of an Enterprise Objects Frameworks adaptor for JNDI data sources.


Interface Summary
JNDIPlugIn.ChannelOperation The ChannelOperation interface encapsulates an operation to be performed in the JNDIChannel.
JNDIType The JNDIType class represents the external type of an EOAttribute.

Class Summary
JNDIAdaptor The JNDIAdaptor class represents a Java Naming and Directory Interface service.
JNDIChannel The JNDIChannel class represents a communication channel to a Java Naming and Directory Interface service.
JNDIContext The JNDIContext class represents a transaction scope on a Java Naming and Directory Interface service.
JNDIPlugIn The JNDIPlugIn class represents a plug-in to the JNDIAdaptor.
LDAPPlugIn The LDAPPlugIn class represents a plug-in to the JNDIAdaptor for Lightweight Directory Access Protocol services.

Exception Summary
JNDIAdaptorException The JNDIAdaptorException class represents a runtime exception that wraps an instance of NamingException.

Package com.webobjects.jndiadaptor Description

Provides an implementation of an Enterprise Objects Frameworks adaptor for JNDI data sources.

The Java Naming and Directory Interface (JNDI) enables connectivity to heterogeneous enterprise naming and directory services, including but not limited to the Lightweight Directory Access Protocol (LDAP). Sun distributes several different service providers for use with JNDI, such as an LDAP service provider and a file service provider (see http://java.sun.com/products/jndi/index.html).

The JNDI adaptor has a plug-in architecture that allows developers to change the behavior of the adaptor or even to implement a plug-in for a new kind of directory service. Currently, the JNDI adaptor supports only one plug-in, the LDAP plug-in. In theory, one could write a plug-in for another directory service, such as NetInfo. The class of the plug-in used by the adaptor is specified in the EOModel's connection dictionary.

Basic Features

Like the JDBC adaptor, the JNDI adaptor supports basic read and write operations as well as integration with the EOModeler application. Using EOModeler, one can create a model that uses the JNDI adaptor. With a JNDI model, one can use the data browser window in EOModeler to look at the entries on a server. The JNDI adaptor supports reverse engineering of data sources, but reverse engineering can only be used if the server to be modeled accepts connections and makes information about the schema publicly available. Not all public LDAP servers publish a schema.

With the JNDI adaptor one can write a WebObjects application to fetch, insert, update, and delete objects that correspond to entries in a naming and directory service. In fact, creating a fully functional, administrative application is trivial when using Direct to Web or Direct to Java Client.


The JNDI adaptor does not support schema synchronization. It is expected that the JNDI adaptor will be used with LDAP servers that come with pre-defined schemas. Third-party tools or other mechanisms exist for modifying schemas.

The LDAP plug-in (see below) does not support the use of key-comparison qualifiers mostly because LDAP does not support the comparison of attribute values.

Another issue concerns the flattening of attributes and relationships. Although one can create a relationship between an entity in a JNDI model and an entity in a JDBC model, EOF currently will not support the flattening of attributes or relationships between entities in models that use different adaptors.


The plug-in has large control over the behavior of the JNDI adaptor. For example, one could change the way that the initial directory context gets created by creating a subclass of the LDAPPlugIn class that overrides the createInitialDirContext method. Remember to specify the new plug-in name in the connection dictionary of the model. For further details, see the reference documentation for the JNDIPlugIn class.

One could also write a plug-in to specify the external types to be used for a directory service. The JNDIType interface represents the external type of an EOAttribute. The JNDI adaptor relies on JNDIType to store the knowledge required to do the "raw guts" of the adaptation between JNDI and EOF. The LDAPPlugIn class implements the jndiTypes method to return a set of JNDITypes for use with LDAP. For further details, see the reference documentation for the JNDIType and JNDIPlugIn classes.

Another compelling reason to write a customized plug-in is to enable authentication using a different security scheme, such as Kerberos.

Relative Distinguished Name

The distinguished name is a unique, human-readable identifier of an entry in a naming and directory service. The relative distinguished name is the distinguished name minus the search base (the base is usually related to the domain of a server). For example, suppose the distinguished name of an entry is

 cn=Ernest Hemingway,dc=apple,dc=com

and the base of the server is


In such a case, the relative distinguished name is:

 cn=Ernest Hemingway

which is the part of the distinguished name up to but excluding the base.

In a JNDI model, every entity has exactly one attribute named relativeDistinguishedName which holds the value of the relative distinguished name and serves as the primary key. By default, reverse engineering sets the relativeDistinguishedName attribute to be neither a class property nor an attribute that participates in locking.

Although a relative distinguished name is similar to EOF's definition of a primary key, there are differences. While in EOF most often an integer type is used, with values that are usually not visible to the user, in JNDI/LDAP the relative distinguished name is of type String, and usually in a human readable form. More importantly, in EOF the primary key is usually an independently determined value, whereas in JNDI/LDAP, the relative distinguished name is in general derived from the values of other attributes. For a "Person" entity, a JNDI/LDAP database might use the first plus the last name of a person instead of a hidden unique number.

There are basically two ways to handle the creation or generation of new relative distinguished names (primary keys) with the JNDI adaptor:

There are provisions to alter the automatic behavior: Subclassing and overriding the specific plug-in methods the JNDI adaptor uses to generate relative distinguished names. The methods to override are relativeDistinguishedNameForNewRow (defined in the JNDIPlugIn class) and convertSpecialCharactersForDistinguishedName (defined in the LDAPPlugIn class). See the descriptions of these methods for more detail.

If this value of the relative distinguished name contains special characters (, = + < > # ; and even more special \ and "), the JNDI adaptor uses a special syntax for the value (but not for the attribute): Conforming with RFC 2253 (and 1779), these are escaped by preceding them with a backslash "\". Two exceptions are the "more special" characters backslash and quote, for which this doesn't (always) work. For these two characters, their hexadecimal notation (again according to RFC 2253) is used, which is "#5C" and "#22", respectively.

Unfortunately some servers handle special characters in a very unique way, and the above scheme doesn't work with all of them. If the server you use does not work with this scheme, your application needs to handle special characters explicitly or you should consider avoiding the use of special characters in relative distinguished names completely.

Object Class

The object class represents the type of an entry on a directory server. One way to think of an object class is as a static collection of attributes. At some level, the idea of an object class is similar to that of a class in a programming language like Java. In a JNDI model, every entity has exactly one attribute named objectClass which holds the value of the object class.

By default, reverse engineering sets the objectClass attribute to be neither a class property nor an attribute that participates in locking. Although not a primary key, the objectClass is not a property in the common sense. The reason is that the type of an entry is static (much like the class of an object in Java), as opposed to a property that is, in principle, dynamic or variable.

An object class can extend or inherit attributes from another object class. For example, the attributes of the object class "person" include:

 aci, cn, description, objectclass, seeAlso, sn, telephonenumber, userpassword

The object class "organizationalPerson" extends "person" and has all of the above attributes plus:

 destinationindicator, facsimiletelephonenumber, internationalisdnnumber, l, ou,
 physicaldeliveryofficename, postofficebox, postaladdress, postalcode,
 preferreddeliverymethod, registeredaddress, st, street, teletexterminalidentifier,
 telexnumber, title, x121address

Since an "organizationalPerson" entry is also a "person" entry, a search on the "person" object class will also yield entries from the "organizationalPerson" object class.

In a JNDI model created by reverse engineering, there may be an entity Person that corresponds to the "person" object class and an entity OrganizationalPerson for the "organizationalPerson" object class. For each attribute in the object class, there is an attribute in the entity in addition to the relativeDistinguishedName and objectClass attributes. The OrganizationalPerson entity, however, does not necessarily extend the Person entity.

Fetching on the Person entity also returns "organizationalPerson" rows; however, only the Person attributes will be visible because each row is treated as an instance of the Person entity. Thus, there is a subtle but important distinction to be made between object class inheritance in a directory service and entity inheritance in the EOF.


The LDAPPlugin that is part of the JNDI adaptor communicates with LDAP directory servers. It performs LDAP queries and updates from within a WebObjects application by using the JNDI API's to communicate to one or more LDAP servers. This communication is not encrytped, so saving user names, passwords, or other sensitive information can be dangerous from a security standpoint.

The default authentication mechnisms offered by the JNDI adaptor are None and Simple. In the None configuration, no authentication to the directory is performed and all operations are performed annonymously. In the Simple configuration, a user name and password are used to bind to the directory before performing dirrectory operations, but the server cannot guarantee that the user working with the directory is truly who they claim to be.

The plug-in architecture of the JNDI adaptor allows you to use other authentication mechanisms like Kerberos while communicating with an LDAP directory server and to encrypt the communication: The purpose of a KerberosLDAPPlugin would be to look like a regular LDAPPlugin, while performing all of its directory operations in a channel through JAAS as a Kerberos princpal that has been authenticated through GSSAPI. The necessary steps for such a plug-in would be:

Last updated Thu Oct 21 15:04:16 PDT 2004.

Copyright © 2004 Apple Computer, Inc.