|
From commons-dev post by Stephane Demurget 13-nov-07. Shows not removing listener when connection is removed from pc map causes an exception when a connection is returned when maxIdle is reached.
Thread [pool-5-thread-4] (Suspended (exception IllegalStateException)) GenericKeyedObjectPool.returnObject(Object, Object) line: 997 After analyzing it a bit I understand the pool wants to destroy the object public void destroyObject(Object key, Object obj) throws Exception { Which means it removes the mapping and close the PooledConnection. At this public void connectionClosed(ConnectionEvent event) { Modified patch applied in r598045.
To eliminate the potential for ConcurrentModificationExcepotions (which PooledConnectionImpl was throwing), I removed the listener removal from connection event handlers. This required refactoring to decouple listener and pcMap cleanup from connection event handling. Cleanup is now performed in makeObject. Leaving issue open, since similar changes should be made for CPDSConnectionFactory. Completed fix in r814240
1) Modified fix applied in r598045:
2) Applied the same fix to CPDSConnectionFactory |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Regarding 2., with current backing pool (o.a.c.pool.GenericKeyedObjectPool), the destroy -> invalidate change (2.) will only work for active (i.e., checked out) connections and in this case it is necessary, but not to "remove from the pool," but to maintain integrity of the active count. Unfortunately, the contract of the pool's invalidate method only applies to objects that have been borrowed from the pool, so if the (exception-generating) connectionClosed event originates from from an idle connection, this will not work. This should not happen in general though, since these events should come from handles from checked out connections.
Test cases illustrating the problem in this ticket should be added before committing the patch.