Skip to content
Rupesh Bhochhibhoya edited this page Dec 17, 2015 · 14 revisions

What is JNDI and why we needed it?

When you build an application, chances are you have to depend on some other resources built by somebody else. There is a directory or naming service that maps or bind name to such resources so that you can use simply know the name and get the resource into your application. Such resources could be an object or simply just location to object. Such services are important because it provides way to expose the those resources to be used and reused. For instance:

  • DNS maps people-friendly names (such as www.google.com) into computer-friendly IP addresses in dotted-quad notation (227.69.175.36)
  • LDAP provide access to hierarchical structural information about users, networks or systems over IP network through url and other attributes names.
  • NIS (Network Information System) or NIS+ provides access to file and application resources through ID and password

So, the common thing is they all are naming systems that binds the name to the object of our interest. Those objects or resources may or may not be on the same host and just be reference to object. No mater where they are naming service provide the lookup service to find such object by name.

The difference is the naming convention each of those naming services has undertaken. For instance:

  • DNS uses the dot notation to construct the full domain name. (www.google.com)
  • LDAP uses comma to separate the components while uses key/value pair to distinguish each components. ('cn=Rupesh Bho, o=ComPlus, c=US') .

With such differences, it would be nightmare for the application developers if they have to spend writing code to bring various naming servers every time they work on the application. This is where JNDI comes into play.

JNDI is a API which provides the uniform standard to access any naming or directory services into your application. Remember JNDI is just interface, not implementation.

Architecture

JNDI Architecture

JNDI architecture consists of API and Service Provider Interface(SPI). Java application use the JNDI API to access a variety of naming and directory services. The SPI enables a variety of naming and directory services to be plugged in transparently, thereby allowing the Java application using JNDI API to access their services.

JNDI is included in Java SE. To use JNDI, you must have the JNDI classes and one or more service providers. Some service providers like LDAP, RMI and DNS are included with the JDK, other you can find from other vendors.

How it works?

Let explain with simple example. jndi-example is the sample app that demonstrate how to integration the naming/directory services into your application. In the example I have connected filesystem as well as LDAP. Following are important notes to remember.

  • You need to prepare the properties, the environment information need to connect naming service. Such information are specific to JNDI provider. You can serve these environment information using Properties or HashTable. Checkout following snippet for connect filesystem and LDAP naming system.
  // connecting filesystem using Properties class
  Properties props = new Properties();
  props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
  props.put(Context.PROVIDER_URL, "file:///");
  //connecting LDAP using HashTable class
  Hashtable<String, String> env = new Hashtable<String, String>();
  env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
  env.put(Context.PROVIDER_URL, "ldap://ldap.host.com:port");
  env.put(Context.SECURITY_AUTHENTICATION,"simple");
  env.put(Context.SECURITY_PRINCIPAL,"username"); // specify the username
  env.put(Context.SECURITY_CREDENTIALS,"password"); // specify the password
  • You need to build a context. A Context in JNDI plays the central role. A context represents a set of bindings within a naming service. Context object provides methods for binding names to objects and unbinding names from objects, for renaming objects or for listing the bindings. Following snippet shows how to create initial context from each JNDI provider
Context initialContext = new InitialContext(props);
LdapContext initialContext = new InitialLdapContext(env,null);		
  • Finally, once you have Context, you can do all sorts of operations, like search, authenticate, enumerate, add binding or remove one etc. Following snippet shows listing all binding in filesystems and listing all users in ldap directory.
 //print all properties 
 NamingEnumeration namingEnum = initialContext.list("");
 while (namingEnum.hasMore()) {
 System.out.println(namingEnum.next());
 SearchControls searchControl = new SearchControls();
 searchControl.setSearchScope(SearchControls.SUBTREE_SCOPE);
 searchControl.setTimeLimit(30000);
 NamingEnumeration<?> namingEnum = initialContext.search("ou=bix,dc=host,dc=com","(objectclass=user)",searchControl);
 while (namingEnum.hasMore()) {
   SearchResult result = (SearchResult) namingEnum.next();
   Attributes attrs = result.getAttributes();
   System.out.println(attrs.get("cn"));
 }
  • That's all about JNDI. Check out the example for code reference.