Troubleshooting
Problem
You experience a ClassNotFoundException for the initial context factory when attempting to use Java™ Naming and Directory Interface (JNDI) from a CICS Java program hosted in a Java Virtual Machine (JVM) Server. For example, using the com.ibm.websphere.naming.WsnInitialContextFactory from the WebSphere Application Server thin client.
Cause
JNDI is an application programming interface (API) that can be implemented by many different vendors. It is often necessary to use a specific vendor's JNDI Factory when connecting to their JNDI server. For example, if you wish to use the JNDI API in a CICS Java program to interact with a WebSphere JNDI server, you would add the WebSphere client jar file to your CICS Java environment.
The java.naming.factory.initial property is used to specify the vendor specific factory class that the javax.naming classes should load. In an OSGi environment bundles have to identify the packages they are allowed to import, so the standard javax.naming classes do not have visibility to load vendor specific classes, causing the ClassNotFoundException.
Environment
JVM server
Diagnosing The Problem
Stack trace will return:
Caused by: java.lang.ClassNotFoundException: com.ibm.websphere.naming.WsnInitialContextFactory
at java.lang.Class.forName(Class.java:176)
at com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper12.java:75)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:682)
Resolving The Problem
Use of an OSGi JNDI registry service. For example, the open source Apache Aries project provides the infrastructure required for such a service here: http://aries.apache.org/modules/jndiproject.html .
CICS Transaction Server for z/OS (CICS TS) V5.1 and later enables a JNDI registry service automatically.
For CICS TS V4.2, you will need to provide your own version.
The registry service enables JNDI implementation classes to register themselves within the OSGi framework. This will typically happen when the JVM is started. The javax.naming classes use the registry in order to resolve the registered JNDI implementation classes on behalf of the application.
In addition to a registry, you will also need a suitable OSGi bundle for the JNDI implementation classes, and an OSGi Activator to register the vendor specific JNDI Factory class. The vendor specific OSGi Bundle might include an Activator, but this is not always the case. For example, the WebSphere thin client is an OSGi bundle that includes the implementation classes for the JNDI service, but at time of writing it does not include an OSGi Activator for JNDI.
It might be necessary to supply your own Activator for JNDI. If you need to do so, the following example might be helpful. It is suitable for use with CICS TS V4.2, and CICS TS V5.1 or later. It demonstrates an Activator for the IBM WebSphere JNDI initial context factory:
public class JNDIActivator implements org.osgi.framework.BundleActivator
{
- public void start (org.osgi.framework.BundleContext bundleContext) throws java.lang.Exception
{
- // Load the WebSphere JNDI Initial Context Factory
javax.naming.spi.InitialContextFactory initialContextFactory
- = new com.ibm.websphere.naming.WsnInitialContextFactory();
// Find the factory class names to register
String[] interfaceNames =
{
- javax.naming.spi.InitialContextFactory.class.getName(), com.ibm.websphere.naming.WsnInitialContextFactory.class.getName()
// Register the class names with the Service Registry
org.osgi.framework.ServiceRegistration serviceRegistration =
- bundleContext.registerService(interfaceNames,
initialContextFactory, null);
public void stop (org.osgi.framework.BundleContext bundleContext) throws java.lang.Exception
{
}
The OSGI manifest for the Activator above would be similar to the following:
Manifest-Version: 1.0
Created-By: 1.5.0 (IBM Corporation)
Bundle-ManifestVersion: 2
Bundle-Name: JNDI Activator for WAS thin client
Bundle-SymbolicName: was.jndi.activator
Bundle-Version: 1.0
Bundle-RequiredExecutionEnviornment: J2SE-1.6
Bundle-Activator: JNDIActivator
Import-Package:
com.ibm.websphere.naming, org.osgi.framework
The JNDI Activator will need compiling and packaging into a CICS Bundle as normal. You can then install the Activator Bundle just like any other CICS OSGi Bundle.
The key field in the OSGi manifest file above is the 'Bundle-Activator' line. This identifies a class that will run as the OSGi Bundle is activated. The OSGi framework will call the start() method of the Activator as the Bundle is initialized, and the Activator will register the JNDI Initial Context Factory with the JNDI registry service. All of this will happen before the application is used. When the application runs, the javax.naming.* classes should be able to resolve the vendor specific JNDI implementation classes using the Initial Context Factory that was previously registered.
Some JNDI implementations might have further dependencies that need importing into the Activator bundle, and registering with the Service Registry. For example, if the IBM MQ JNDI implementation is used, the following services may need to be registered in the Activator:
- // Find the factory class names to register
String[] interfaceNames =
{
- InitialContextFactory.class.getName(), RefFSContextFactory.class.getName()
// Register the class names with the Service Registry
ctx.registerService(interfaceNames, new RefFSContextFactory(), null);
// Load the MQ object factories ctx.registerService(MQConnectionFactoryFactory.class.getName(), new MQConnectionFactoryFactory(), null);
ctx.registerService(MQQueueConnectionFactoryFactory.class.getName(), new MQQueueConnectionFactoryFactory(), null);
ctx.registerService(MQTopicConnectionFactoryFactory.class.getName(), new MQTopicConnectionFactoryFactory(), null);
ctx.registerService(MQTopicFactory.class.getName(), new MQTopicFactory(), null);
ctx.registerService(MQQueueFactory.class.getName(), new MQQueueFactory(), null);
Product Synonym
CICS/TS CICS TS CICS Transaction Server
Was this topic helpful?
Document Information
Modified date:
15 June 2018
UID
swg21608608