Warum nicht DirContext.close() return die LDAP-Verbindung an den pool?

Bemerkte ich während der Verwendung einer LDAP-Verbindung-pool, der Aufruf close() auf den Kontext offenbar nicht zurück in den pool, trotz der Dokumentation sagen sonst. So, wenn ich Versuch, ein Element aus dem pool, wenn es schon bei seiner max Größe, hängt es.

Habe ich es geschafft es zu beschränken, um eine minimale Falle. Obwohl ich glaube, ich rufe close() auf alle relevanten Objekte deterministisch, es scheint, verlassen sich auf die garbage collection, um tatsächlich die Objekte zurückgeben, um den pool, die unerwartet ist. Warum ist das passiert? Gibt es eine andere Objekt sollte ich schließen?

In das code-snippet unten:

  • Ich habe künstlich legen Sie die maximale pool-Größe auf 1 markieren Sie das problem.
  • Ich eine DirContext aus dem pool (Zeile (2)), Versuch es zurück an den pool (Zeile (4)), dann bekommen die anderen einen aus dem pool (Zeile (6)), die sollten wieder den gleichen, zurückgegebene Objekt.
  • statt, die zweite Anforderung (Zeile (6)) hängt einige interne Aufruf Object.wait(). Ich vermute, es wartet eine zusammengefasste Objekt verfügbar werden.
  • wenn ausschalten-pooling durch auskommentieren (1), hängt Sie nicht (aber ich möchte pooling!).
  • wenn ich kommentiere (3) - ein Aufruf von SearchResults.next() - es funktioniert gut.
  • wenn ich die Auskommentierung Zeile (5) erzwingen, dass die garbage collection zwischen dem "return to pool' nennen, und die Anforderung ein neues Objekt an den pool, wird es nicht hängen.

Seit auskommentieren der Zeile (3) ist das problem Weg, vielleicht bin ich nicht die Schließung der return-Wert es richtig, und es hält die zusammengefasste Verbindung öffnen. Allerdings ist die Methode results.next() gibt eine SearchResult in diesem Fall, die hat keine close Methode und keine Anleitung in der Dokumentation auf, wie um es zu schließen sauber.

Testfall:

@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)
}

Mit dem code, wie es ist, meine Konsole zeigt:

Create com.sun.jndi.ldap.LdapClient@1a7bf11[ldapad:389]
Use com.sun.jndi.ldap.LdapClient@1a7bf11

In der Erwägung, dass, wenn ich die Kraft der GC, die ich zusätzlich finden Sie unter:

Release com.sun.jndi.ldap.LdapClient@93dee9 <-- on GC
Use com.sun.jndi.ldap.LdapClient@93dee9     <-- on new InitialDirContext
InformationsquelleAutor bacar | 2012-08-14
Schreibe einen Kommentar