【发布时间】:2012-02-05 22:30:51
【问题描述】:
我有一种情况,通过 Java 程序,我创建了一个 javax.naming.ldap.LdapContext 并对其执行 search() 操作 - 这建立了一个底层连接。然后我让 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
【问题讨论】:
-
如果您没有更改任何绑定用户,我认为重启服务器后应该不会出现问题。
-
您好 Imran,很遗憾 - 在 LDAP 服务器重新启动后,LdapContext 上的所有操作都失败并出现 CommunicationException。
-
您能否分享一些代码,您是如何创建连接并使用它进行搜索的?
-
我正在使用 Active Directory。我重新启动服务器并搜索。它没有给我任何异常并且搜索完成。
-
@Anand:我遇到了和你一样的问题。由于 Jan 13 没有活动,看来您已经找到了解决方案。如果您与我们分享,我将不胜感激。谢谢
标签: java exception ldap reconnect