Search code examples
javajakarta-eejbossdnsjndi

Failure to Instantiate DnsContextFactory on JBoss 7


When attempting to create a new InitialDirContext using the com.sun.jndi.dns.DnsContextFactory on JBoss AS 7, the following exception occurs:

Caused by: javax.naming.NamingException: Failed instantiate InitialContextFactory com.sun.jndi.dns.DnsContextFactory from classloader ModuleClassLoader for Module "deployment.test-case.ear.test-web.war:main" from Service Module Loader
        at org.jboss.as.naming.InitialContextFactoryBuilder.createInitialContextFactory(InitialContextFactoryBuilder.java:58)
        at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:664) [:1.6.0_26]
        at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288) [:1.6.0_26]
        at javax.naming.InitialContext.init(InitialContext.java:223) [:1.6.0_26]
        at javax.naming.InitialContext.(InitialContext.java:197) [:1.6.0_26]
        at javax.naming.directory.InitialDirContext.(InitialDirContext.java:82) [:1.6.0_26]
        at com.test.messaging.internal.resource.dns.DnsClientImpl.querySrv(DnsClientImpl.java:328) [dns-lookup-jar.jar:]
        ...

16:36:36,000 ERROR [org.apache.catalina.core.StandardContext] (MSC service thread 1-5) Error listenerStart
16:36:36,013 ERROR [org.apache.catalina.core.StandardContext] (MSC service thread 1-5) Context [/test] startup failed due to previous errors
16:36:36,023 INFO  [org.jboss.web] (MSC service thread 1-5) registering web context: /test

Here is the relevant code snippet:

Hashtable env = new Hashtable();
env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
env.put("java.naming.authoritative", "false");
env.put("com.sun.jndi.dns.recursion", "true");
env.put("com.sun.jndi.dns.timeout.initial", timeoutProp);
env.put("com.sun.jndi.dns.timeout.retries", "1");
env.put("java.naming.provider.url", providerProp);
DirContext ctx = new InitialDirContext(env);

The code is invoked from within a ServletContextListener and therefore the exception prevents the module from starting. I've also removed the listener and have attempted to invoke the code from within a servlet, which produced the same results (javax.naming.NamingException: Failed instantiate InitialContextFactory com.sun.jndi.dns.DnsContextFactory).

I found this thread which seemed very similar to the problem that I am running into, but setting the "jboss.modules.system.pkgs" property to "com.sun.jndi.dns," as the thread mentions, had no effect.

The code works correctly on JBoss 6, WebSphere Application Server 7, and Geronimo 2.2.1 (on Tomcat 6), but is failing on JBoss 7 as described above. I'm running JBoss AS 7.0.0.Final and testing using the standalone server, using the 1.6.0_26 JRE. Any suggestions on how to resolve this problem would be greatly appreciated.

I also posted this question on the JBoss development community forum, but have not received any replies.


[UPDATE] It seems this problem is likely related to JBoss 7's new isolated, modular class loading policies. I found two workarounds/solutions to this problem, but I'm still interested in suggestions on the most appropriate, recommended approach, particularly if there is a way that we can avoid manual modifications to our applications or JBoss installations.

MANIFEST.MF

  • Create a com.sun.jndi.dns module, by copying $JBOSS_HOME/modules/com/sun/jndi/ldap to $JBOSS_HOME/modules/com/sun/jndi/dns and modify occurrences of "ldap" to "dns"

  • Add the following entry to the web module's MANIFEST.MF: Dependencies: com.sun.jndi.dns

Although this now allows the DnsContextFactory to instantiate properly, this doesn't seem to be a permanent solution since it requires modification of all JBoss installations as well as all applications that use the DnsContextFactory.

jboss-deployment-structure.xml

  • Add a jboss-deployment-structure.xml file to the EAR's META-INF directory, as follows:

    <sub-deployment name="test-web.war">
        <dependencies>
            <module name="deployment.com.sun.jndi.dns" />
        </dependencies>
    </sub-deployment>
    
    <module name="deployment.com.sun.jndi.dns">
        <dependencies>
            <module name="system" export="false">
                <exports>
                    <include-set>
                        <path name="com/sun/jndi/dns"/>
                    </include-set>
                </exports>
            </module>
        </dependencies>
    </module>
    

This is slightly better than the previous "MANIFEST.MF" approach, since it only requires modification to the application, and not also the JBoss modules, but is unfortunate that all applications that use the DnsContextFactory must include this configuration.

I'm still looking for suggestions on the most appropriate, recommended approach, particularly if there is a way that we can avoid including more JBoss-specific configuration in our applications.


Solution

  • Thanks to some help on the JBoss forum, it's been confirmed that the workarounds I mentioned above may work, but the most appropriate solution requires a feature request from JBoss. I've logged this feature request, and in the meantime, another temporary solution is to add the "com/sun/jndi/dns" path to the sun.jdk module descriptor ($JBOSS_HOME/modules/sun/jdk/main/module.xml).