मैं जबकि प्रलेखन sayingotherwise के बावजूद, एक LDAP पूल इस संदर्भ पर close()
बुला यह पूल पर लौटने के लिए प्रकट नहीं किया था कनेक्ट का उपयोग कर देखा। इस प्रकार जब मैं पूल से आइटम प्राप्त करने का प्रयास करता हूं, जब यह पहले से ही अपने अधिकतम आकार में होता है, तो यह लटकता है।क्यों DirContext.close() पूल में एलडीएपी कनेक्शन वापस नहीं करता है?
मैं एक न्यूनतम मामले को उसे संक्षिप्त में कामयाब रहे। भले ही मेरा मानना है कि मैं निर्धारित सभी प्रासंगिक वस्तुओं पर close()
पर कॉल कर रहा हूं, ऐसा लगता है कि वास्तव में पूल में वस्तुओं को वापस करने के लिए कचरा संग्रह पर निर्भर है, जो अप्रत्याशित है। ऐसा क्यों हो रहा है? क्या कोई अन्य वस्तु है जो मुझे बंद करनी चाहिए?
नीचे कोड स्निपेट में:
- मैं कृत्रिम समस्या को उजागर करने के 1 करने के लिए अधिकतम पूल आकार निर्धारित किया है।
- मैं पूल से एक
DirContext
मिल (लाइन (2)), प्रयास यह पूल पर लौटने के लिए (लाइन (4)), तो पूल से एक और एक (लाइन (6)) मिलता है जो एक ही वापस जाने के लिए चाहिए वस्तु वापस कर दिया। - बजाय, दूसरा अनुरोध (लाइन (6))
Object.wait()
को कुछ आंतरिक फोन पर लटका हुआ है। मुझे लगता है कि यह एक पूल ऑब्जेक्ट उपलब्ध होने की प्रतीक्षा कर रहा है। - अगर बाहर टिप्पणी करके पूलिंग बंद करें (1), यह लटका नहीं है (लेकिन मैं पूलिंग करना चाहता हूं!)।
- अगर मैं बाहर टिप्पणी (3) -
SearchResults.next()
के लिए एक कॉल - यह ठीक काम करता है। - अगर मैं टिप्पणी हटाएं लाइन (5) की वापसी पूल करने के लिए 'कॉल और पूल करने के लिए एक नई वस्तु का अनुरोध के बीच कचरा संग्रहण के लिए मजबूर करने, लटका नहीं करता है।
लाइन से टिप्पणी करने के बाद (3) समस्या दूर हो जाती है, शायद मैं इसका सही मूल्य बंद नहीं कर रहा हूं, और यह पूल कनेक्शन को खुला रख रहा है। हालांकि, विधि results.next()
इस मामले में SearchResult
लौटाती है, जिसमें close
विधि नहीं है और इसे अपने दस्तावेज़ में साफ-सफाई के तरीके पर कोई मार्गदर्शन नहीं है।
परीक्षण का मामला:
@Test
public void testHangs() throws NamingException {
System.setProperty("com.sun.jndi.ldap.connect.pool.debug", "fine");
System.setProperty("com.sun.jndi.ldap.connect.pool.maxsize", "1");
Hashtable<String,String> env = new Hashtable<String,String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.SECURITY_PRINCIPAL, user);
env.put(Context.SECURITY_CREDENTIALS, passwd);
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.PROVIDER_URL, ldapUrl);
// use a connection pool
env.put("com.sun.jndi.ldap.connect.pool", "true"); // ----------------- (1)
// get a context from the pool.
DirContext context = new InitialDirContext(env); // -------------------- (2)
NamingEnumeration<SearchResult> results = context.search("", query, getSC());
// obviously the next two lines would normally be in a
// while(results.hasMore()) { ... = results.next(); } loop.
assertTrue(results.hasMore()); // this is only a problem when there are some results.
results.next(); // ----------------------------------------------------- (3)
// ensure the context is returned to the pool.
results.close();
context.close(); // ---------------------------------------------------- (4)
//System.gc(); // ------------------------------------------------------ (5)
new InitialDirContext(env); // hangs here! ---------------------------- (6)
}
कोड यह है के रूप में के साथ, मेरे कंसोल पता चलता है:
Create [email protected][ldapad:389]
Use [email protected]
जबकि यदि मैं जीसी मजबूर मैं अतिरिक्त देखें:
Release [email protected] <-- on GC
Use [email protected] <-- on new InitialDirContext
धन्यवाद! यह निराशाजनक है कि दस्तावेज कहता है कि एलडीएपी प्रदाता के लिए पूल किए गए कनेक्शन को सही तरीके से प्रबंधित करने के लिए आदेश में, आपको संदर्भों पर Context.close() को आमंत्रित करने के बारे में मेहनत करनी चाहिए, जिनकी आपको अब आवश्यकता नहीं है, फिर भी यह समझ में नहीं आता कि आप अर्थपूर्ण तरीके से कैसे कर सकते हैं यह न ही आपको बताएगा कि कौन सी प्रदत्त वस्तुएं स्वयं इन वस्तुओं को पकड़ सकती हैं जिन्हें बंद करने की भी आवश्यकता है। – bacar
यदि आप लूप जारी रखते हैं, तब तक 'results.next() 'झूठी रिटर्न देता है, कनेक्शन स्वचालित रूप से बंद हो जाता है। – EJP