ClassNotFoundException when using custom SSLSocketFactory

2022-09-04 23:39:19

我创建了一个自定义的SSSOCKETFactory类,并将其设置为如下所示

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

LdapContext ldapContext = new InitialLdapContext(ldapEnv, null);

当从 Eclipse Dev Environment 运行,并从命令提示符将其作为 Jar 文件运行时,它可以正常工作。但是,当我将其包装在服务包装器中并将其作为Windows服务启动时,它不起作用。我得到以下异常,

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

任何帮助???


答案 1

似乎这个问题可能是由于 JNDI 依赖于设置正确的线程上下文类装入器(管理员可能没有这样做),这是必需的,因为 JNDI 类是由装入器层次结构基础的类装入器装入的,并且该类装入器找不到由应用程序/容器类装入器装入的类。因此,JNDI 提供了一个钩子,用于通过线程上下文类装入器装入此类类。

看看这是否有效,

 // 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 );

答案 2

自从我发布这个问题以来已经很久了。由于这篇文章没有任何答案,并且似乎也得到了一些观点,我想我可以分享我当时所做的工作,以最终解决它(几年前我已经在问题的评论部分发布了这个问题)。

我能够通过使用选项将该jar文件包含在引导加载程序类路径中来解决此问题。但无论如何,我不喜欢这个解决方案。-Xbootclasspath/a:


推荐