Previous | Next | Trail Map | Java Objects and the Directory | Storing Objects in the Directory

Referenceable Objects and References

You can think of the serialized state of an object as a copy of the object in a different representation. Sometimes it is not appropriate to store that representation in the directory. This is because the serialized state might be too large or it might be inadequate for your needs (the application, for example, might need more information than can be supplied by the serialized form). Or, you might need the object in a different form.

For reasons such as these, the JNDI defines a reference for use when (the serialized form of) an object cannot be stored in the directory directly. You store an object with an associated reference in the directory indirectly by storing its reference. It might be useful to think of the distinction between a serialized object and a JNDI reference as that between a copy of a Java object and a Java object reference.

What's in a Reference?

A reference is represented by the class Reference(in the API reference documentation). A Reference consists of an ordered list of addresses and class information about the object being referenced. Each address is represented by a subclass of RefAddr(in the API reference documentation) and contains information on how to construct the object.

References are commonly used to represent connections to a network service such as a database, directory, or file system. Each address may then identify for that service a communication endpoint that contains information on how to contact the service. Multiple addresses might arise for various reasons, such as the need for replication or multiple access points (that is, the object offers interfaces over more than one communication mechanism).

A reference also contains information to assist in creating an instance of the object to which the reference refers. It contains the Java class name of that object, as well as the class name and location of the object factory to be used to create the object.

Referenceable Objects

An object whose class implements the Referenceable(in the API reference documentation) interface has an associated reference. The Referenceable interface has one method, getReference()(in the API reference documentation), which returns the reference of the object.

The following example shows a Fruit class that implements the Referenceable interface.

public class Fruit implements Referenceable {
    String fruit;
    
    public Fruit(String f) {
	fruit = f;
    }
    
    public Reference getReference() throws NamingException {
	return new Reference(
	    Fruit.class.getName(),
	    new StringRefAddr("fruit", fruit),
	    FruitFactory.class.getName(),
	    null);          // Factory location
    }

    public String toString() {
	return fruit;
    }
}
The reference of a Fruit instance consists of a single address (of class StringRefAddr(in the API reference documentation)). This address contains the fruit type with which the instance was created. For example, if the instance was created using new Fruit("orange"), then its address type would be "fruit" and its address contents "orange". The reference contains two additional pieces of information: the fully qualified name of the Fruit class (in this case, simply "Fruit") and the fully qualified name of the object factory class that can be used to create instances of Fruit (in this case, "FruitFactory"). Object factories are described in the Object Factories (in the Java Objects and the Directory trail) lesson.

Binding a Referenceable Object

You might remember the Fruit class from the Adding a Binding That Has Attributes (in the Basics trail) example. The following example is a simplification of that example.

After creating an instance of Fruit, you invoke Context.bind()(in the API reference documentation), DirContext.bind()(in the API reference documentation), Context.rebind()(in the API reference documentation), or DirContext.rebind()(in the API reference documentation) to add it to the directory.

// Create the object to be bound
Fruit fruit = new Fruit("orange");
...

// Perform bind
ctx.bind("cn=favorite", fruit);
The service provider implementation of bind()/rebind() first extracts the reference from the object being bound (by using Referenceable.getReference()) and then stores that reference in the directory. When that object is subsequently looked up from the directory, its corresponding object factory will convert the reference into an instance of the object (conversion details are described in the Object Factories (in the Java Objects and the Directory trail) lesson).
// Read the object back
Fruit f2 = (Fruit) ctx.lookup("cn=favorite");
System.out.println(f2);
This produces the following output, "orange", produced by Fruit.toString().
# java RefObj
orange

From the perspective of the application using the JNDI, it is dealing only with bind() and lookup(). The service provider takes care of getting the reference from the object and converting it to/from the actual object itself.

Note that you can store a Referenceable object in the directory only if the underlying service provider supports it. Sun's LDAP service provider supports storing both References and Referenceable objects.

Binding a Reference

Binding a Referenceable object is more elegant than binding a Reference directly. This is because you can simply bind the object instead of first getting its reference. However, you can also bind a Reference directly. See the Remote Objects (in the Java Objects and the Directory trail) section for an example of binding a Reference.


Previous | Next | Trail Map | Java Objects and the Directory | Storing Objects in the Directory