Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
2.2
-
None
-
jdk1.7.0_55 on CentOS6
Description
I found BasePooledObjectFactory.validateObject() of commons-pool sometimes called on unexpected timing.
I've configured the pool so as to the validateObject() would be invoked only on instance creation, but sometimes it was invoked for "non-fresh" instance on borrowing.
Reproduction code below.
import java.io.*; import java.util.*; import org.apache.commons.pool2.*; import org.apache.commons.pool2.impl.*; public class reproduction { private static class MyPooledObj { volatile int i = 0; final String uuid = UUID.randomUUID().toString(); } private static class MyFactory extends BasePooledObjectFactory<MyPooledObj> { @Override public MyPooledObj create() { return new MyPooledObj(); } @Override public PooledObject<MyPooledObj> wrap(MyPooledObj o) { return new DefaultPooledObject<MyPooledObj>(o); } @Override public boolean validateObject(PooledObject<MyPooledObj> o) { MyPooledObj myobj = o.getObject(); synchronized (myobj) { myobj.i++; } System.out.println("Validated."); return true; } } public static void main(String[] args) throws Exception { GenericObjectPoolConfig poolCfg = new GenericObjectPoolConfig() ; poolCfg.setMaxTotal(1); poolCfg.setMaxIdle(1); poolCfg.setBlockWhenExhausted(true); poolCfg.setMaxWaitMillis(10000); poolCfg.setTestOnCreate(true); // should be validated only on creation poolCfg.setTestOnBorrow(false); poolCfg.setTestOnReturn(false); poolCfg.setTestWhileIdle(false); final GenericObjectPool<MyPooledObj> pool = new GenericObjectPool<MyPooledObj>(new MyFactory(), poolCfg); final MyPooledObj o = pool.borrowObject(); System.out.printf("%d: %s\n", o.i, o.uuid); Timer t = new Timer(); t.schedule (new TimerTask() { public void run() { pool.returnObject(o); } }, 3000); // validation will occur again for non-fresh instance, // confirmed on commons-pool2-2.2 with jdk1.7.0_55 MyPooledObj o2 = pool.borrowObject(); System.out.printf("%d: %s\n", o2.i, o2.uuid); pool.returnObject(o2); pool.close(); t.cancel(); } }