How to configure WildFly naming subsystem

This tutorial shows how you can configure the naming subsystem in WidFly and older JBoss AS versions

The Java Naming and Directory Interface (JNDI) is a Java API for a directory service that allows Java software clients to discover and look up data and objects via a name. Like all other Java APIs also, JNDI is independent of the underlying implementation, however it specifies a service provider interface (SPI) that allows directory service implementations to be plugged into the framework.

The Enterprise resources (such as Datasources and JMS destinations) are stored in the JNDI tree so that they can be consumed by applications which are deployed on the application server. Neverthless you can use JNDI to store attributes which will be used by the server/severs a bit like application properties. In this case the advantage of using JNDI instead of basic Properties is that JNDI provides a tree structure for bindings which you don’t have in a simple Property file. (Please note that if you plan to store/cache data structures achieving fully control on them, consider using Infinispan framework).

Let’s see how you can configure your application server to store some JNDI bindings in different AS versions:

WildFly naming subsystem

WildFly ships wth a naming subsystem which contains the bindings element. The Jakarta EE platform specification defines the following JNDI contexts:

  • java:comp – The namespace is scoped to the current component (i.e. EJB)
  • java:module – Scoped to the current module
  • java:app – Scoped to the current application
  • java:global – Scoped to the application server

In addition to the standard namespaces, WildFly also provides the following two global namespaces:

  • java:jboss
  • java:/

Please note that only entries within the java:jboss/exported context are accessible over remote JNDI. For web deployments java:comp is aliased to java:module, so EJB’s deployed in a war do not have their own comp namespace.

In order to add some JNDI bindings to the application server just add some name/value attributes in it:

<subsystem xmlns="urn:jboss:domain:naming:1.1">
  <bindings>
       <simple name="jndi/mykey" value="MyJndiValue"/>
  </bindings>
</subsystem>

Simple JNDI bindings can be looked with Resource injection. For example:

@Resource(lookup = "jndi/mykey")
private String hello;

Object Factory binding

The Object factory can be used to deploy custom Java Objects in the JNDI tree. For example, suppose you have the following Bean:

package com.example;
public class Customer implements java.io.Serializable
  {
      private String name;
      private String surname;
 
      public Customer(String name,String surname)
       {
         this.name=name;
         this.surname=surname;
         
       }
 
      public String getName()  
       {
          return name;
       }      
      public String getSurname()  
       {
          return surname;
       }      
  }

Then, in order to bind a Complex Data type value in the JNDI tree we will need to create a class which implements the javax.naming.spi.ObjectFactory interface and the getObjectInstance() method of this class should return the object which we want to bind in the JNDI tree of JBoss as following:

package com.example;

import java.util.Enumeration;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;
public class MyCustomObjectFactory implements ObjectFactory 
   {
       public MyCustomObjectFactory() 
       {
            System.out.println("[MyCustomObjectFactory] MyCustomObjectFactory initialized.");
       }
 
       public Object getObjectInstance(Object obj, Name name, Context nameCtx,Hashtable environment) throws Exception 
       {
            Customer c = new Customer("John","Smith");
            return c;
       }
   }

Now compile both classes and package them in a JAR file, let’s say customBinding.jar. Create and install a module named “test.jndi.demo” which contains the module.xml and the JAR file:

<module xmlns="urn:jboss:module:1.1" name="test.jndi.demo">
    <resources>
        <resource-root path="customBinding.jar"/>
    </resources>
    <dependencies>
        <module name="javax.api"/>
    </dependencies>
</module>

Then, include the definition of the object-factory in your naming subsystem:

<object-factory name="java:jboss/exported/mycustomer" module="test.jndi.demo" class="com.example.MyCustomObjectFactory"/>

Reload the configuration. You can now use the Object Factory via JNDI as follows:

@Resource(lookup = "mycustomer"
Customer customer;

Naming Alias

Naming alias was introduced in earlier JBoss AS release to create a link from a JNDI binding to another. You can think about it as a symbolic link in Unix Systems. This can be useful for example if you are migrating from one application server JNDI binding structure to another and the JNDI bindings are stored in your application code.

In order to achieve naming aliases you can use the name and  lookup attribute of the lookup element:

<subsystem xmlns="urn:jboss:domain:naming:1.1">
     <bindings>
         <lookup name="java:global/MyOldEJB" lookup="java:global/my-ear/my-ejb-module/ExampleEJB"/>
     </bindings>
</subsystem>

JBoss AS 4-5-6

In earlier JBoss AS releases, the org.jboss.naming.JNDIBindingServiceMgr is a service which allows one to bind arbitrary values into JNDI.

<server>
    <mbean code="org.jboss.naming.JNDIBindingServiceMgr" name="pm-urls:service=JNDIBindingServiceMgr">
        <attribute name="BindingsConfig" serialDataType="jbxb">
           <jndi:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
                xmlns:jndi="urn:jboss:jndi-binding-service:1.0"
                xs:schemaLocation="urn:jboss:jndi-binding-service:1.0 resource:jndi-binding-service_1_0.xsd">

                         <jndi:binding name="jndi/binding/port">
                           <jndi:value type="java.lang.Integer">443</jndi:value>
                         </jndi:binding>
                         <jndi:binding name="jndi/binding/protocol">
                           <jndi:value type="java.lang.String">https</jndi:value>
                         </jndi:binding>
                    </jndi:bindings>
        </attribute>
        <depends>jboss:service=Naming</depends>
    </mbean>
</server>

Naming Alias

The NamingAlias MBean is the utility service that allows you to create an alias in the form of a JNDI javax.naming.LinkRef from one JNDI name to another. To an alias you add a configuration of the NamingAlias MBean to the jboss-service.xml configuration file. The configurable attributes of the NamingAlias service are as follows:

FromName : The location where the LinkRef is bound under JNDI.

ToName : The to name of the alias. This is the target name to which the LinkRef refers. The name is a URL, or a name to be resolved relative to the InitialContext, or if the first character of the name is a dot (.), the name is relative to the context in which the link is bound.

The following example provides a mapping of the JNDI name QueueConnectionFactory to the name ConnectionFactory.

<mbean code="org.jboss.naming.NamingAlias" 
       name="jboss.mq:service=NamingAlias,fromName=QueueConnectionFactory">
    <attribute name="ToName">ConnectionFactory</attribute>
    <attribute name="FromName">QueueConnectionFactory</attribute>
</mbean>
Found the article helpful? if so please follow us on Socials