14

I have created a custom SSLSocketFactory class and set it as below

ldapEnv.put(Context.SECURITY_PROTOCOL, "ssl");
ldapEnv.put(FACTORY_SOCKET, socketFactoryClass);

LdapContext ldapContext = new InitialLdapContext(ldapEnv, null);

It works fine when running from Eclipse Dev Environment, and running it as Jar file from command prompt. But it doesn't work when I wrap it inside a service wrapper and launch it as Windows Service. I get the following exception,

javax.naming.CommunicationException: 192.168.100.22:636 [Root exception is java.lang.ClassNotFoundException: com/testing/diraccess/service/ActiveDirectory$TestSSLFactory]
at com.sun.jndi.ldap.Connection.<init>(Unknown Source)
at com.sun.jndi.ldap.LdapClient.<init>(Unknown Source)
at com.sun.jndi.ldap.LdapClient.getInstance(Unknown Source)
at com.sun.jndi.ldap.LdapCtx.connect(Unknown Source)
at com.sun.jndi.ldap.LdapCtx.<init>(Unknown Source)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(Unknown Source)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(Unknown Source)
at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(Unknown Source)
at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(Unknown Source)
at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
at javax.naming.InitialContext.init(Unknown Source)
at javax.naming.ldap.InitialLdapContext.<init>(Unknown Source)

Caused by: java.lang.ClassNotFoundException: com/testing/diraccess/service/ActiveDirectory$TestSSLFactory
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at com.sun.jndi.ldap.VersionHelper12.loadClass(Unknown Source)
at com.sun.jndi.ldap.Connection.createSocket(Unknown Source)
... 35 more

Any help ???

user207421
  • 305,947
  • 44
  • 307
  • 483
Jagadish G
  • 671
  • 6
  • 18
  • 2
    Is the JAR containing the class, accessible to the user running the Windows service? – Vineet Reynolds Nov 24 '11 at 08:21
  • Can you post the windows service configuration ? – Santosh Nov 24 '11 at 08:35
  • Do you know exactly where the `com/testing/diraccess/service/ActiveDirectory$TestSSLFactory` class resides. Is it in the separate library that wasn't included in your jar? – MockerTim Nov 24 '11 at 09:05
  • Yes, the JAR containing the class is accessible to the user running the windows service. – Jagadish G Nov 24 '11 at 09:25
  • com/testing/diraccess/service/ActiveDirectory$TestSSLFactory class is in a separate jar file which is in the class path of the application jar file and is accessible to the user running it. – Jagadish G Nov 24 '11 at 09:26
  • I have even configured the Windows Service to run as a user with administrator privileges, but it didn't help. Any other ideas ?? – Jagadish G Nov 24 '11 at 09:30
  • 1
    Clearly it *isn't* accessible. – user207421 Nov 24 '11 at 09:33
  • If it is not accessible, is there any way, I can troubleshoot/debug it ? I would appreciate, if you could provide some links to tools that can help troubleshooting this kind of issue. – Jagadish G Nov 24 '11 at 09:40
  • 1
    You've got one. The JVM. It will stop throwing that exception when you make that JAR file accessible. You need to review the contents and placement of the JAR file and the startup parameters for the service. – user207421 Nov 24 '11 at 10:01
  • Have you tried to put the jar, that contains that class, into `JRE_HOME/lib/ext` folder? Try it to make yourself sure that you have the `CLASSPATH` problem. – MockerTim Nov 24 '11 at 10:39
  • 1
    @MockerTim Poor advice. That directory is not provided for that purpose. It is for approved Java extensions. *Any* other directory will do as long as the JAR is on the CLASSPATH. No need to pollute JVM installations. – user207421 Nov 24 '11 at 21:05
  • Hey, I'm able to resolve this issue by including that jar file in boot loader class path using -Xbootclasspath/a: option. But I don't like this solution anyway. – Jagadish G Nov 29 '11 at 05:16
  • Can't you just merge these two jars into a single one (there are many ways to achieve this, see e.g. [here](http://stackoverflow.com/q/81260/5128464))? In most cases this just works... – vlp Dec 10 '15 at 20:35
  • Do you use maven to manage this development? – malaguna Dec 11 '15 at 08:09

2 Answers2

0

Seems this issue could be due to JNDI's dependence on setting the correct thread context classloader (which admin might not be doing), this is required because JNDI classes are loaded by a class loader at the base of the loader heirarchy and that classloader will not find the classes loaded by application/container class loader. So JNDI provides a hook to load such classes via the thread context class loader.

See if this works,

 // Save the current thread context class loader
 ClassLoader currentCL = Thread.currentThread().getContextClassLoader();

// Set the context class loader to the one we know for sure loaded classes inside configstore-core.jar
Thread.currentThread().setContextClassLoader(OmParticipant.class.getClassLoader());

// Invoke the jndi related code that will internally try to load our socket factory impl
...

//restore the original class loader
Thread.currentThread().setContextClassLoader(currentCL );
Frank Wu
  • 53
  • 2
0

It's been a very long time since I posted this question. Since this post doesn't have any answers and also seems to be getting some views, I thought I could share what I did then to resolve it finally (I had already posted this in comments section of the question years ago).

I was able to resolve this issue by including that jar file in boot loader class path using -Xbootclasspath/a: option. But I didn't like this solution anyway.

Jagadish G
  • 671
  • 6
  • 18