Uploaded image for project: 'Commons Pool'
  1. Commons Pool
  2. POOL-276

Validation code invoked on unexpected timing.

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 2.2
    • Fix Version/s: 2.3
    • Labels:
      None
    • Environment:

      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();
          }
      }
      

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              nori Noriyuki Torii
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: