Hi,
can you give the latest version (not released yet) a try? (You'll have
to checkout the code base and build it)
On 20/12/2024 15:35, Andreas Schufft wrote:
Hi,
we encountered the same problem as described in ticket DIRAPI-398 in
older versions of the API (before 2.1.7). The connection pools filled up
because the close method on the underlying LdapConnection simply closed
the connection instead of returning the connection to the pool. We build
a workaround for us based on Proxy.newProxyInstance( , new
Class[]{LdapConnection.class}). This works fine for. Starting with the
latest release 2.1.7 we wanted to remove our own proxy and use the
pooling provided by the API but unfortunaly this doesn't work for us.
When an object becomes returned to the pool (by calling
releaseConnection the underlying pool throws an exception:
IllegalStateException: Returned object not currently part of this pool
I checked also the PooledLdapConnectionTest which contains a test
(closeReleasesToPool) but this test only ferifies that the
releaseConnection method is called on the pool. Unfortunaly I didn't
find any integration tests which would show the problem.
A simple test which is executed against a real LDAP shows the problem:
@Test
void closeReleasedToPoolValidating() throws IOException,
LdapException {
final LdapConnectionConfig config = new LdapConnectionConfig();
config.setLdapHost( "testldap" );
config.setLdapPort(389);
final PooledObjectFactory factory = new
DefaultPoolableLdapConnectionFactory(config);
LdapConnectionPool pool = new LdapConnectionPool(factory);
try
{
final LdapConnection connection = pool.getConnection();
Assertions.assertDoesNotThrow(() -> connection.close());
}
catch( final Exception e ) {
Assertions.fail(e);
}
}
This will fail with the following error:
org.opentest4j.AssertionFailedError: Unexpected exception thrown:
java.lang.RuntimeException: java.lang.IllegalStateException: Returned
object not currently part of this pool
at
org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:152)
at
org.junit.jupiter.api.AssertDoesNotThrow.createAssertionFailedError(AssertDoesNotThrow.java:84)
at
org.junit.jupiter.api.AssertDoesNotThrow.assertDoesNotThrow(AssertDoesNotThrow.java:53)
at
org.junit.jupiter.api.AssertDoesNotThrow.assertDoesNotThrow(AssertDoesNotThrow.java:36)
at
org.junit.jupiter.api.Assertions.assertDoesNotThrow(Assertions.java:3199)
at
org.apache.directory.ldap.client.api.PooledLdapConnectionTest.closeReleasedToPoolNonValidating(PooledLdapConnectionTest.java:84)
at java.lang.reflect.Method.invoke(Method.java:498)
at java.util.ArrayList.forEach(ArrayList.java:1259)
at java.util.ArrayList.forEach(ArrayList.java:1259)
Caused by: java.lang.RuntimeException: java.lang.IllegalStateException:
Returned object not currently part of this pool
at
org.apache.directory.ldap.client.api.LdapConnectionPool.releaseConnection(LdapConnectionPool.java:189)
at
org.apache.directory.ldap.client.api.PooledLdapConnection.close(PooledLdapConnection.java:49)
at
org.apache.directory.ldap.client.api.PooledLdapConnectionTest.lambda$closeReleasedToPoolNonValidating$1(PooledLdapConnectionTest.java:84)
at
org.junit.jupiter.api.AssertDoesNotThrow.assertDoesNotThrow(AssertDoesNotThrow.java:49)
... 6 more
Caused by: java.lang.IllegalStateException: Returned object not
currently part of this pool
at
org.apache.commons.pool2.impl.GenericObjectPool.returnObject(GenericObjectPool.java:1031)
at
org.apache.directory.ldap.client.api.LdapConnectionPool.releaseConnection(LdapConnectionPool.java:176)
... 9 more
When I debug the test I can see that the object within the Pool
GenericObjectPool.allObjects contains the value DefaultPooledObject with
a PooledLdapConnection as object. The PooledLdapConnection contains the
attribute connection of type LdapNetworkConnection.
So the Pool contains objects of type PooledLdapConnection, but the
PooledLdapConnection will try to release the underlying connection to
the pool and this fails.
The LdapConnectionPool#getConnection borrows an object from the pool
(type PooledLdapConnection), but the PooledLdapConnection#close method
tries to return the connection attribute of the PooledLdapConnection.
The behaviour is a little bit different whether you use the final
DefaultPoolableLdapConnectionFactory or a
ValidatingPoolableLdapConnectionFactory. The error is the same, but the
object in the pools are of a different type.
If you are using the DefaultPoolableLdapConnectionFactory the pool
consists of PooledLdapConnection objects (wrapping LdapNetworkConnection
objects). When you are using a ValidatingPoolableLdapConnectionFactory
the pool consists of MonitoringLdapConnection object (wrapping
PooledLdapConnection objects).
Our only solution to this problem is staying on version 2.1.6 with our
dynamic proxy object.
Thanks
Andreas
---------------------------------------------------------------------
To unsubscribe, e-mail: api-unsubscr...@directory.apache.org
For additional commands, e-mail: api-h...@directory.apache.org
--
*Emmanuel Lécharny* P. +33 (0)6 08 33 32 61
elecha...@apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: api-unsubscr...@directory.apache.org
For additional commands, e-mail: api-h...@directory.apache.org