JNDI Example Introduction

This project shows an example of using the JNDI API for storing references to ActiveSpaces Transactions managed objects in an LDAP directory.

Please see the enclosed source and javadoc for this example.

Overview

This example demonstrates how to store references to ActiveSpaces Transactions Managed Objects in an LDAP directory using the JNDI API. The example further demonstrates how those references can be looked up from the directory at a later time, and then converted to standard Java references to the actual Managed Object instances.

Functional Description

Reference Construction

The following utility method is used for obtaining the naming reference to a ActiveSpaces Transactions Managed Object: com.kabira.platform.swbuiltin.ObjectServices.objectToString().

This reverse method is used for converting the naming reference back to the object itself: com.kabira.platform.swbuiltin.ObjectServices.stringToObject().

Representation in the Directory

The LDAP schema used to store the object references is defined in RFC 2713 "Schema for Representing Java(tm) Objects in an LDAP Directory". The example uses the javaNamingReference LDAP object class defined there, which is a subclass of the javaObject directory object class.

A typical entry representing a UserProfile object reference in the directory looks as follows in LDIF notation:

 dn:                            cn=xyz,ou=objects,dc=kabira,dc=com
 objectclass:                   top
 objectclass:                   javaContainer
 objectclass:                   javaObject
 objectclass:                   javaNamingReference
 javaReferenceAddress:  theRef
 javaClassName:         com.kabira.examples.jndi.UserProfile
 javaFactory:                   com.kabira.examples.jndi.UserProfileFactory
 cn:                            theCommonName

where the 'theRef' stands in for some actual object identifier (reference) value and the 'theCommonName' for some actual naming attribute value. The cn (common name) directory attribute is used as the unique naming attribute for the javaNamingReference entries.

As can also be seen, the object reference entries are stored under the "ou=objects,dc=kabira,dc=com" node in the directory tree.

Java API

The example relies on the following two object classes:

  • UserProfile class - a managed object that implements the javax.naming.Referenceable interface. The implementation produces a javax.naming.Reference instance that contains the class name, the factory class name and the unique object identifier for the UserProfile object.
  • UserProfileFactory class - a factory class that converts the reference into an instance of the UserProfile object.

The example carries out the following actions:

  • The "example.jndi.properties" file is loaded, and its values are displayed. The property values will be used to connect to the LDAP server.
  • An instance of a UserProfile object is created. This instance is an ActiveSpaces Transactions Managed Object.
  • The UserProfile object reference is published in the LDAP directory. The object is stored in the directory twice - under two different directory names: cn=Name1 and cn=Name2.
  • An LDAP lookup of the two bound names is used to obtain two UserProfile object references. During these lookup operations, JNDI uses the UserProfileFactory class to convert the naming references retrieved from the LDAP directory to actual Java objects references.
  • The example verifies that the two UserProfile object references resolved from the LDAP directory point to the single UserProfile Managed Object created by the example.

Using Example

Building and Running

This project uses the deploy:exec target to invoke the main class on an ActiveSpaces Transactions server. See the documentation for the TIBCO ActiveSpaces Transactions Deployment Maven plugin for more information on configuring the client connectivity.

This example requires a running LDAP server. The parameters example.ldaphost and example.ldapport provide the connection details, modifying the jndi properties file.

The following invocation will run the example on the ActiveSpaces Transactions Development Appliance:

NOTE: kabira-server.local only works on OS X. Other platforms may use a different name, or have to specify an IP address.

mvn -Dcom.kabira.fluency.hostname=kabira-server.local \
    -Dcom.kabira.fluency.administrationPort=2000 \
    -Dcom.kabira.fluency.domainNode=A \
    -Dexample.ldaphost=10.170..... \
    -Dexample.ldapport=3890 \
    compile resources:resources deploy:exec

Running The Example Without Maven

To run the example without Maven, from an IDE, for example, edit the example.jndi.properties file to contain the network address of the LDAP server in the "java.naming.provider.url" property.

Example Output

The example displays the following output:

Loading example properties ...
getting system classloader ...
getting example.jndi.properties ...

JNDI properties found in example.jndi.properties:
-- listing properties --
java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
java.naming.provider.url=ldap://172.16.93.138:389/ou=objects,d...
java.naming.security.principal=cn=admin,dc=kabira,dc=com
java.naming.security.credentials=secret

Loaded example properties ok.
createUserProfile() starting up ...
Creating UserProfile object ...
User profile 'FluencyUser' has been created.
createUserProfile(): all done!
publishUserProfile() starting up ...
User profile 'FluencyUser' has been bound to the name 'cn=Name1'
User profile 'FluencyUser' has been bound to the name 'cn=Name2'
publishUserProfile(): all done!
lookupUserProfile() starting up ...
UserProfileFactory: resolving reference: 783509:2634352:2001:4
Lookup succeeded for name 'cn=Name1'.
UserProfileFactory: resolving reference: 783509:2634352:2001:4
Lookup succeeded for name 'cn=Name2'.
'cn=Name1' and 'cn=Name2' refer to the same ActiveSpaces Transactions Managed
Object, as expected.
lookupUserProfile(): all done!

Dependencies

See the Dependencies page for information on the example's dependencies.

For each dependency listed in the Project Dependencies section of the Dependencies page, the example's POM (or parent POM) defines a property specifying the version of the dependency used by the example. These properties can be overridden if there is a need to change the dependency versions used by the example. The names of these properties are of the form com.tibco.groupId.artifactId.version where groupId and artifactId are the group id and artifact id of the dependency. For example, the property named com.tibco.com.tibco.ast.version specifies the version of the dependency with the group id of com.tibco and the artifact id of ast.