The Java Naming and Directory Interface (JNDI) is an Application Programming Interface (API) that provides naming and directory services to Java-based applications. We can use this interface to bind objects/resources, look up or query objects, and detect changes on the same objects.
In this tutorial, we’ll look specifically into the background behind using the “java:comp/env” standard prefix in the JNDI naming.
2. What Is the Java Naming and Directory Interface?
In simple terms, a Naming Service is an interface to associate names with objects and, subsequently, find those objects with the help of names. As such, the Naming Service maintains a set of bindings that maps names with objects.
The JNDI API enables the application components and the clients to look up the distributed resources, services, and EJB.
3. Accessing the Naming Context
The Context interface provides access to the naming environment. Using this object, we can bind names to objects, rename objects, and list the bindings. Let’s see how to get the context:
JndiTemplate jndiTemplate = new JndiTemplate(); context = (InitialContext) jndiTemplate.getContext();
Once we have the context, we can bind the object:
Then, we can retrieve the objects present in the context:
4. What Is java:comp/env?
As seen in the earlier example, we bind a name with a standard prefix “java:comp/env“. In our case, it’s “java:comp/env/jdbc/datasource” and not just “jdbc/datasource“. Is this prefix mandatory? Can we avoid it completely? Let’s discuss.
4.1. Directory Service
JNDI, as the name indicates, is a Naming and Directory service. Accordingly, a directory service associates names with objects and also permits such objects to have attributes. Hence, we not only can look up an object by its name but also get the object’s attributes or find the object based on its attributes. A live example is a telephone directory service where a subscriber’s name is mapped not only to his phone number but also to his address.
Directories often arrange the objects in a hierarchy. In most cases, directory objects are stored in a tree structure. So, the first element/node might contain group objects that might, in turn contain specific objects.
For instance, in “java:comp/env” the “comp” element is the first node, and on the next level, it contains the “env” element. From here, we can store or access the resources based on our convention. For example, “jdbc/datasource” to share a data source object.
4.2. The Split-up
Let’s break up our previous naming example: “java:comp/env/jdbc/datasource“.
- java is just like “jdbc:” from the JDBC connection string. It acts as a protocol.
- comp is the root of all JNDI contexts. It’s bound to a subtree reserved for component-related bindings. The name “comp” is short for component. There are no other bindings in the root context.
- env the name “env” is bound to a sub-tree that is reserved for the component’s environment-related bindings. “env” is short for environment.
- jdbc is the subcontext for jdbc resources. There are other types, or sub-contexts for connection factories.
- datasource is the name of our JDBC resource.
Here, except the last element, all other parent elements are standard names and thus can’t be changed.
In addition, the root context is reserved for the future expansion of the policy. Specifically, this applies to naming resources that aren’t tied to the component itself but to other types of entities, such as users or departments. For example, future policies might allow us to name users and organizations/departments by using names such as “java:user/Anne” and “java:org/finance“.
5. Relative vs. Absolute Paths
In case we want to use a shorter version of JNDI lookup, we can do it with the help of sub-context. This way, we don’t need to mention the full path (absolute path) of the naming, but a relative path of the sub-context.
We can derive a sub-context from the InitialContext object so that we don’t have to repeat the “java:comp/env” for every resource we retrieve:
Context subContext = (Context) context.lookup("java:comp/env"); DataSource ds = (DataSource) subContext.lookup("jdbc/datasource");
As we can see here, we created a sub-context that holds the values inside “java:comp/env” and then used this sub-context (relative path) to look up the specific namings within it.
In this article, we quickly went through what is JNDI and its use cases. Then, we saw how to bind a JNDI name to the context and look up the same.
Subsequently, we saw the split-up of the standard prefix: “java:comp/env” and the reason for using this prefix in JNDI naming. We also noted that the future policies might well expand both the root context “comp” and the sub-context “env“.
As always, all code samples used in this article are available over on GitHub.