9

我有一种情况,通过 Java 程序,我创建一个javax.naming.ldap.LdapContextsearch()对其进行操作 - 这建立了一个底层连接。然后我让 Java 应用程序线程进入睡眠状态,在此期间我重新启动 LDAP 服务器(OpenLDAP,请注意)。当 App 线程唤醒并尝试对LdapContext之前创建的执行任何操作时,它会抛出“ CommunicationException: Connection is closed”。

我想要的是能够重新建立连接。

我看到LdapContext有一个reconnect()方法 - 我将控件传递为null. 但是,这没有任何效果。我在 Sun LDAP 实现中看到,在 LDAP 服务器重新启动期间,由 Sun 实现维护的 ConnectionPool 将底层com.sun.jndi.ldap.LdapClient实例标记为“usable=false”。在reconnect()调用时 - 它只是调用ensureOpen(),它再次检查usable标志是否false- 如果是false; 然后它抛出CommunicationException- 所以回到第一方。

我的问题是:Java 应用程序如何在外部 LDAP 服务器重启后幸存下来?重新创造新事物LdapContext是唯一的出路吗?欣赏任何见解。

这是异常的堆栈跟踪:

javax.naming.CommunicationException: connection closed [Root exception is java.io.IOException: connection closed]; remaining name 'uid=foo,ou=People,dc=example,dc=com'
at com.sun.jndi.ldap.LdapCtx.doSearch(LdapCtx.java:1979)
at com.sun.jndi.ldap.LdapCtx.searchAux(LdapCtx.java:1824)
at com.sun.jndi.ldap.LdapCtx.c_search(LdapCtx.java:1749)
at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_search(ComponentDirContext.java:368)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:338)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:321)
at javax.naming.directory.InitialDirContext.search(InitialDirContext.java:248)
Caused by: java.io.IOException: connection closed
at com.sun.jndi.ldap.LdapClient.ensureOpen(LdapClient.java:1558)
at com.sun.jndi.ldap.LdapClient.search(LdapClient.java:504)
at com.sun.jndi.ldap.LdapCtx.doSearch(LdapCtx.java:1962)
... 26 more
4

4 回答 4

2

只需启用 JNDI 连接池,它就会在幕后为您处理好。请参阅 JNDI 功能指南和 LDAP 提供者文档。它仅由几个属性控制。

于 2013-08-04T00:56:27.323 回答
0

我们在工作中遇到了这个问题。我们提出的解决方案(可能不是最佳答案)。是创建一个看门狗线程,以某个固定速率检查连接。如果连接不起作用,它将重新初始化与 LDAP 的连接。

于 2013-08-03T18:17:53.647 回答
0

UnboundID LDAP SDK提供了一种自动连接的方法,其中自动重新连接操作对客户端是不可见的。

于 2012-01-09T13:55:25.267 回答
-1

您应该注意,这本质上与 LDAP 连接池有关。如此处定义:

从池中检索、使用、返回到池中的连接,然后再次从池中检索到另一个 Context 实例。

因此,重用以前的连接可能会导致这样的问题:

您可以通过设置在不使用 LDAP 连接池的情况下测试行为

com.sun.jndi.ldap.connect.pool=false

此外,另一个可能的原因可能是读取 LDAP 操作超时。实际上,在特定超时后,不会通知读取操作关闭 LDAP 服务器。有关更多信息,您可以查看此链接

于 2013-02-11T14:40:04.327 回答