2012-01-09 141 views
8

我有一种情况,通过Java程序,我创建了一个javax.naming.ldap.LdapContext并对其执行了一个search()操作 - 它构成了一个基础连接。然后我让Java应用程序线程进入休眠状态,在此期间我重新启动LDAP服务器(OpenLDAP,仅供参考)。当App线程唤醒并尝试对之前创建的LdapContext执行任何操作时,它会抛出“CommunicationException: Connection is closed”。如何在重新启动LDAP服务器时重新连接?

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

我看到LdapContext有一个reconnect()方法 - 在那里我将控件作为null传递。但是,这没有任何影响。我在Sun LDAP实现中看到,在重新启动LDAP服务器期间,由Sun实施维护的ConnectionPool将标记为“可用= false”的底层com.sun.jndi.ldap.LdapClient实例。在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 
+0

如果您没有更改任何绑定用户,我认为重新启动服务器后应该出现问题。 – 2012-01-09 13:05:16

+0

不幸的是,不幸的是,在重新启动LDAP服务器之后,LdapContext上的所有操作都会因CommunicationException而失败。 – Anand 2012-01-09 16:21:50

+0

你可以请分享一些代码,你如何创建连接并使用它来搜索? – 2012-01-10 05:20:59

回答

0

UnboundID LDAP SDK提供了一种手段来自动连接其特征在于,自动重新连接操作是不可见的客户端。

-1

您应该注意到这主要与LDAP连接池有关。如定义here

连接从池中检索,使用,返回到池中,然后再从池中检索另一个上下文实例。

因此,先前的连接的重用可以引起这样的问题:

您可以通过设置

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

另外测试行为而不使用LDAP连接池,另一个可能的原因可能是读取LDAP操作的超时。实际上,读取操作在特定的超时后没有被通知关闭LDAP服务器。欲了解更多信息,你可以看看this link

+0

默认情况下,连接池处于关闭状态。我的最后一段没有什么意义。如果服务器在阅读过程中出现故障,您肯定会收到通知。 – EJP 2016-08-25 21:24:21

0

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

2

只需启用JNDI连接池,它将在幕后为您完成。请参阅JNDI功能指南和LDAP提供程序文档。它由几个属性控制。

相关问题