In addition to the below, I have had a shufftie at the source code for
GenericObjectPool to see if I could work out what was the issue and it
appears that what is suggested in the docs about creating a new object
if validation fails can't happen. If I throw an exception when
makeObject fails, then the borrowObject method also throws it and the
pool lifecycle is interupted. So, I am returning null object which then
is validated. see code below with ----------> annotations
 
           // create new object when needed
            boolean newlyCreated = false;
            if(null == pair) {
                try {
                    Object obj = _factory.makeObject();   ------>  here
obj is null as the makeObject had some difficulty in creating the
object
                    pair = new ObjectTimestampPair(obj); ------> the
value of this object (in the pair) is also null
                    newlyCreated = true;   -------> this is also set to
true, but the object wasn't created successfully (according to
validateObject - but this isn't tested here.
                    return pair.value; -------> as method is returning
here, don't know how we get back into this method to do the activation
and validation
                } finally {
                    if (!newlyCreated) {   ---------> this isn't ever
true unless exception is thrown by makeObject method
                        // object cannot be created
                        _numActive--;
                        notifyAll();
                    }
                }
            }
 
-----> I am guessing makeObject must be called twice if the object was
created on first call that is how we get to activation and validation
 
            // activate & validate the object
            try {
                _factory.activateObject(pair.value);
                if(_testOnBorrow &&
!_factory.validateObject(pair.value)) {
                    throw new Exception("ValidateObject failed");     
------------> fine, I get an exception thrown when validate fails
                }
                return pair.value;
            }
            catch (Throwable e) {
                // object cannot be activated or is invalid
                _numActive--;
                notifyAll();
                try {
                    _factory.destroyObject(pair.value);
                }
                catch (Throwable e2) {
                    // cannot destroy broken object
                }
                if(newlyCreated) {                       
--------------------------------------------> this appears to be testing
the wrong thing. Of course if the object failed validation there is no
validated object. However, we shouldn't be throwing this exception
should we - shouldn't we be attempting to create another in the pool to
return??? and therefore continue here too????
                    throw new NoSuchElementException("Could not create
a validated object, cause: " + e.getMessage());
                }
                else {
                    continue; // keep looping
                }
 
Hi,
<quote>When testOnBorrow is set, the pool will attempt to validate each
object before it is returned from the borrowObject() method. (Using the
provided factory's
PoolableObjectFactory.validateObject(java.lang.Object) method.) Objects
that fail to validate will be dropped from the pool, and a different
object will be borrowed. </quote> from api docs for
org.apache.commons.pool.impl.GenericObjectPool

The last bit about "a different object will be borrowed" doesn't appear
to work in my implementation.
The life cycle I am experiencing with the borrowObject method is
thus...
 
call to borrowObject
createObject is called ----> this is failing so I happen to return null
object
activateObject is called
validateObject is called ---> this is checking to see if object is null
(amongst other things) and returning false if null which is happening
 
however, I am getting an exception 
java.util.NoSuchElementException: Could not create a validated object,
cause: ValidateObject failed
 at
org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:871)
 at uk.police.kent.pnc.PoolDemo.main(PoolDemo.java:23)
 
thrown where I am expecting to get an attempt to create a different
object and this one to be destroyed.
 
The question is, what do I have to do to get this cycle to kick in on
false being returned from validateObject???
 
Thanks
Conrad

Reply via email to