objectPoolConfig.setMinEvictableIdleTimeMillis(TimeUnit.HOURS.toMillis(1)); // arbitrary, but positive so objects do get evicted
objectPoolConfig.setTimeBetweenEvictionRunsMillis(TimeUnit.MINUTES.toMillis(10)); // arbitrary, but positive so objects do get evicted
objectPoolConfig.setJmxEnabled(false);
objectPoolConfig.setBlockWhenExhausted(false);
objectPoolConfig.setMaxTotal(-1); // uncapped number of objects in the pool
final AbandonedConfig abandonedConfig = new AbandonedConfig();
abandonedConfig.setRemoveAbandonedOnBorrow(true);
abandonedConfig.setRemoveAbandonedTimeout((int) TimeUnit.MINUTES.toSeconds(30));
return new GenericObjectPool<T>(factory, objectPoolConfig, abandonedConfig);
}