CICS has long supported JNDI in JVM server environments. The recent announced support for IBM MQ classes for JMS (MQ JMS for the rest of this article) in CICS means that it is likely to be used more frequently. This short article describes JNDI and why you might want to use it.
JNDI stands for Java Naming and Directory Interface. It is a set of interfaces and classes that allow Java objects to be registered, and then later located, using a name, which is typically a string. It is often used in Java Enterprise Edition environments such as WebSphere Application Server (WAS) as it allows applications to access resources such as Java Message Service (JMS) and Java Database Connectivity (JDBC) providers without having to worry about how to create and configure these resources.
To elaborate further, consider the case of creating the MQ JMS object that represents a specific IBM MQ (MQ) queue called Q1. In the most basic case this is pretty simple and can be achieved using the code in listing 1.
Listing 1: Simple queue
MQQueue queue = new MQQueue("Q1");
So, what is bad about this? Well for one thing we now have a hard coded requirement on using MQ, as we have just created an instance of one of the MQ JMS classes - MQQueue. If you did need to swap JMS provider, say to use the Default Messaging Provider in WAS, you would have to change your code. Not ideal.
Further more, there are actually quite a lot of configuration options, 10 at the time of writing, that can be applied programmatically to an MQ queue. For example you could have written something like the code shown in listing 2.
Listing 2: Complicated queue
MQQueue queue = new MQQueue("Q1");
If you use many different queues in an application you could easily imagine this approach getting unwieldy, especially when things change as they inevitably do.
JNDI helps here by allowing the configuration of resources to be separated from the use of those resources. What typically happens is that an administrator creates a JNDI repository, which is the location where JNDI resources are stored; configures a number of resources, such as the MQQueue shown earlier; and then stores the resources in the repository using a key. For example you could create a JNDI repository, administratively create the MQQueue object shown above in listing 2, and then store the object into the repository using the key "myQueue".
To get the queue back out of JNDI in your application you could then use the following code.
Listing 3: JNDI with queue
Context ctx = new InitialContext(properties);
Note that the object that gets returned is actually an MQQueue object, but as no implementation specific methods are being used the javax.jms.Queue interface is sufficient. This approach is much cleaner than directly creating MQ JMS objects. You are not tied to using specific class names, you don't need to worry about configuration, all you need to worry about is your application logic.
In listing 3 the connection to the JNDI repository is encapsulated in the creation of an InitialContext object. This object is part of the JNDI standard and is not tied to any particular JNDI implementation. The properties object that is passed into to the constructor contains the configuration parameters that are needed to specify and configure a connection to a particular JNDI repository. Note that in most cases you only need a couple of parameters to establish a connection to a JNDI repository so it is perfectly feasible to provide these parameters using system properties or something similar.
While there are many different JNDI repository implementations there are two that are usable in more places than others, and are commonly used with MQ JMS. The first of these, the LDAP repository (initial factory class: com.sun.jndi.ldap.LdapCtxFactory) is actually part of the JVM. However this JNDI repository doesn't work in OSGi environments because of the way OSGi class-loading works.
The second is a JNDI repository which is based on the file system (initial factory class: com.sun.jndi.fscontext.RefFSContextFactory). This repository works fine in CICS.
In order to use JNDI in a CICS OSGi JVM server some special steps are required. These are described here.
This article provides an example use of the file system JNDI repository in CICS.
About the author
Matt Leming has worked at the IBM Hursley laboratory for 12 years, either in the WebSphere Application Server or IBM MQ development teams. Currently he works in MQ for z/OS development. He holds an MSc in software engineering from Oxford University and a BSc in mathematics from Loughborough University. He has published several IBM developerWorks articles and recently was an author on the IBM MQ V8 Features and Enhancements Redbook. He has just finished adding support for MQ JMS in CICS OSGi JVM servers.