2012-01-09 264 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提供程序文檔。它由幾個屬性控制。

相關問題