我有一种情况,通过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
实例,其中包含“useful = 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
答案 0 :(得分:2)
只需启用JNDI连接池,它就会在幕后为您完成。请参阅JNDI功能指南和LDAP提供程序文档。它仅由几个属性控制。
答案 1 :(得分:0)
UnboundID LDAP SDK提供了一种自动连接方式,其中自动重新连接操作对客户端是不可见的。
答案 2 :(得分:0)
我们在工作中遇到了这个问题。我们提出的解决方案(可能不是最好的答案)。是创建一个看门狗线程,以固定的速率检查连接。如果连接不起作用,它将重新初始化与LDAP的连接。
答案 3 :(得分:-1)