If one is using DBCP package and enters an incorrect query (a query that would
always fail) for the "validation query", then when a connection is being
requested the code will enter an infinite loop in
GenericObjectPool.borrowObject().
The problem would happen for any other object (not only Connection) if the
validation always fails.
I suggest adding a counter to the validation loop, to be incremented every
time the validation fails. If the specified count is reached, the loop should
be terminated with exception, similar to the "Timeout".
Alternativelly, use the timeout for the validation loop as well, and append
the number of times the validation failed during the wait period.
public synchronized Object borrowObject() throws Exception {
int validationCount = 0; // NEW <<<<
long starttime = System.currentTimeMillis();
for(;;) {
// MOVE HERE <<<<<
if(_maxWait > 0 && ((System.currentTimeMillis() -
starttime) >= _maxWait)) {
throw new NoSuchElementException("Timeout
waiting for idle object [Validation Failures = " +
Integer.toString(validationCount) + "]");
ObjectTimestampPair pair = null;
// if there are any sleeping, just grab one of those
try {
pair = (ObjectTimestampPair)(_pool.removeFirst());
} catch(NoSuchElementException e) { /* ignored */
}
// otherwise
if(null == pair) {
// check if we can create one
// (note we know that the num sleeping is 0, else we wouldn't
be here)
if(_maxActive > 0 && _numActive < _maxActive) {
Object obj = _factory.makeObject();
pair = new ObjectTimestampPair(obj);
} else {
// the pool is exhausted
switch(_whenExhaustedAction) {
case WHEN_EXHAUSTED_GROW:
Object obj = _factory.makeObject();
pair = new ObjectTimestampPair(obj);
break;
case WHEN_EXHAUSTED_FAIL:
throw new NoSuchElementException();
case WHEN_EXHAUSTED_BLOCK:
try {
if(_maxWait <= 0) {
wait();
} else {
wait(_maxWait);
}
} catch(InterruptedException e) {
// ignored
}
// MOVED ABOVE <<<<
// if(_maxWait > 0 && ((System.currentTimeMillis()
- starttime) >= _maxWait)) {
// throw new NoSuchElementException("Timeout
waiting for idle object");
} else {
continue; // keep looping
}
default:
throw new
IllegalArgumentException("whenExhaustedAction " + _whenExhaustedAction + "
not recognized.");
}
}
}
_factory.activateObject(pair.value);
if(_testOnBorrow && !_factory.validateObject(pair.value)) {
try {
_factory.passivateObject(pair.value);
} catch(Exception e) {
; // ignored, we're throwing it out anyway
}
_factory.destroyObject(pair.value);
// NEW: sanity check <<<<<<
if (validationCount++ > 1000000) {
throw new NoSuchElementException("Unable to
aquire validated object. Is your validation condition correct?");
}
} else {
_numActive++;
return pair.value;
}
}
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>