Name: js151677 Date: 08/08/2004 FULL PRODUCT VERSION : M:\>java -version java version "1.4.2_04" Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_04-b05) Java HotSpot(TM) Client VM (build 1.4.2_04-b05, mixed mode) ADDITIONAL OS VERSION INFORMATION : Microsoft Windows 2000 [Version 5.00.2195] A DESCRIPTION OF THE PROBLEM : When a NamingEnumeration is created from DirContext..search() it obviously has a internal connection back to the directory. When the DirContext that created that NamingEnumeration is closed (via DirContext.close()) the 'child' NamingEnumeration's should be closed too. This is analogous to Statement/ResultSet's being closed when a Connection is closed(). STEPS TO FOLLOW TO REPRODUCE THE PROBLEM : Run the test case EXPECTED VERSUS ACTUAL BEHAVIOR : EXPECTED - That the users NamingEnumeration would be closed as a result of the ctx.close() in the finally block ACTUAL - It isn't closed and connections to the directory get exhausted resulting in a hang. REPRODUCIBILITY : This bug can be reproduced always. ---------- BEGIN SOURCE ---------- import java.util.Hashtable; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; import javax.naming.directory.SearchControls; public class Test { /** * */ public Test() { super(); // TODO Auto-generated constructor stub } public static void main(String[] args) throws Exception { try { Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.SECURITY_PRINCIPAL, PRINCIPAL); env.put(Context.SECURITY_CREDENTIALS, PASSWORD); env.put(Context.PROVIDER_URL, "ldap://directory:389/"); DirContext ctx = null; SearchControls sc = new SearchControls(SearchControls.SUBTREE_SCOPE, 0, 0, null, false, false); for (int i = 0; i < 1000; i++) { try { ctx = new InitialDirContext(env); System.out.println( i + ": Got " + ctx); NamingEnumeration users = ctx .search("", "(objectClass=*)", new String[] {}, sc); users.close(); } finally { System.out.print(i + ":Closing " + ctx); ctx.close(); System.out.println(" - CLOSED."); } } } catch (NamingException e) { System.err.println(e); throw e; } } } ---------- END SOURCE ---------- CUSTOMER SUBMITTED WORKAROUND : call users.close() in the finally block too. (Incident Review ID: 295993) ====================================================================== A DESCRIPTION OF THE FIX : The file to be changed is com/sun/jndi/ldap/LdapClient.java The problem is that NamingEnumerations need to be explictly closed otherwise they will hold the connections open. This is from jdk-6_0-ea-src-b47-jrl-11_aug_2005.jar $ diff -u LdapClient.java.orig LdapClient.java --- LdapClient.java.orig 2005-08-18 13:26:33.487425100 -0600 +++ LdapClient.java 2005-08-18 13:27:18.271643700 -0600 @@ -952,6 +952,7 @@ "Malformed '" + attr.getID() + "' attribute value"); } } + enum_.close(); ber.endSeq(); ber.endSeq(); } @@ -999,6 +1000,7 @@ encodeAttribute(ber, attr); } } + enum_.close(); ber.endSeq(); ber.endSeq(); if (isLdapv3) encodeControls(ber, reqCtls); FIX FOR BUG NUMBER: 5084229
|