    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017package org.apache.commons.pool2.impl;
    018
    019import java.io.PrintWriter;
    020import java.io.StringWriter;
    021import java.io.Writer;
    022import java.lang.management.ManagementFactory;
    023import java.lang.ref.WeakReference;
    024import java.lang.reflect.InvocationTargetException;
    025import java.util.Arrays;
    026import java.util.Deque;
    027import java.util.Iterator;
    028import java.util.TimerTask;
    029import java.util.concurrent.ScheduledFuture;
    030import java.util.concurrent.TimeUnit;
    031import java.util.concurrent.atomic.AtomicLong;
    032
    033import javax.management.InstanceAlreadyExistsException;
    034import javax.management.InstanceNotFoundException;
    035import javax.management.MBeanRegistrationException;
    036import javax.management.MBeanServer;
    037import javax.management.MalformedObjectNameException;
    038import javax.management.NotCompliantMBeanException;
    039import javax.management.ObjectName;
    040
    041import org.apache.commons.pool2.BaseObject;
    042import org.apache.commons.pool2.PooledObject;
    043import org.apache.commons.pool2.PooledObjectState;
    044import org.apache.commons.pool2.SwallowedExceptionListener;
    045
    046/**
    047 * Base class that provides common functionality for {@link GenericObjectPool}
    048 * and {@link GenericKeyedObjectPool}. The primary reason this class exists is
    049 * reduce code duplication between the two pool implementations.
    050 *
    051 * @param <T> Type of element pooled in this pool.
    052 *
    053 * This class is intended to be thread-safe.
    054 *
    055 * @since 2.0
    056 */
    057public abstract class BaseGenericObjectPool<T> extends BaseObject {
    058
    059    // Constants
    060    /**
    061     * The size of the caches used to store historical data for some attributes
    062     * so that rolling means may be calculated.
    063     */
    064    public static final int MEAN_TIMING_STATS_CACHE_SIZE = 100;
    065
    066    private static final String EVICTION_POLICY_TYPE_NAME = EvictionPolicy.class.getName();
    067
    068    // Configuration attributes
    069    private volatile int maxTotal =
    070            GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL;
    071    private volatile boolean blockWhenExhausted =
    072            BaseObjectPoolConfig.DEFAULT_BLOCK_WHEN_EXHAUSTED;
    073    private volatile long maxWaitMillis =
    074            BaseObjectPoolConfig.DEFAULT_MAX_WAIT_MILLIS;
    075    private volatile boolean lifo = BaseObjectPoolConfig.DEFAULT_LIFO;
    076    private final boolean fairness;
    077    private volatile boolean testOnCreate =
    078            BaseObjectPoolConfig.DEFAULT_TEST_ON_CREATE;
    079    private volatile boolean testOnBorrow =
    080            BaseObjectPoolConfig.DEFAULT_TEST_ON_BORROW;
    081    private volatile boolean testOnReturn =
    082            BaseObjectPoolConfig.DEFAULT_TEST_ON_RETURN;
    083    private volatile boolean testWhileIdle =
    084            BaseObjectPoolConfig.DEFAULT_TEST_WHILE_IDLE;
    085    private volatile long timeBetweenEvictionRunsMillis =
    086            BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
    087    private volatile int numTestsPerEvictionRun =
    088            BaseObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
    089    private volatile long minEvictableIdleTimeMillis =
    090            BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
    091    private volatile long softMinEvictableIdleTimeMillis =
    092            BaseObjectPoolConfig.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
    093    private volatile EvictionPolicy<T> evictionPolicy;
    094    private volatile long evictorShutdownTimeoutMillis =
    095            BaseObjectPoolConfig.DEFAULT_EVICTOR_SHUTDOWN_TIMEOUT_MILLIS;
    096
    097
    098    // Internal (primarily state) attributes
    099    final Object closeLock = new Object();
    100    volatile boolean closed = false;
    101    final Object evictionLock = new Object();
    102    private Evictor evictor = null; // @GuardedBy("evictionLock")
    103    EvictionIterator evictionIterator = null; // @GuardedBy("evictionLock")
    104    /*
    105     * Class loader for evictor thread to use since, in a JavaEE or similar
    106     * environment, the context class loader for the evictor thread may not have
    107     * visibility of the correct factory. See POOL-161. Uses a weak reference to
    108     * avoid potential memory leaks if the Pool is discarded rather than closed.
    109     */
    110    private final WeakReference<ClassLoader> factoryClassLoader;
    111
    112
    113    // Monitoring (primarily JMX) attributes
    114    private final ObjectName objectName;
    115    private final String creationStackTrace;
    116    private final AtomicLong borrowedCount = new AtomicLong(0);
    117    private final AtomicLong returnedCount = new AtomicLong(0);
    118    final AtomicLong createdCount = new AtomicLong(0);
    119    final AtomicLong destroyedCount = new AtomicLong(0);
    120    final AtomicLong destroyedByEvictorCount = new AtomicLong(0);
    121    final AtomicLong destroyedByBorrowValidationCount = new AtomicLong(0);
    122    private final StatsStore activeTimes = new StatsStore(MEAN_TIMING_STATS_CACHE_SIZE);
    123    private final StatsStore idleTimes = new StatsStore(MEAN_TIMING_STATS_CACHE_SIZE);
    124    private final StatsStore waitTimes = new StatsStore(MEAN_TIMING_STATS_CACHE_SIZE);
    125    private final AtomicLong maxBorrowWaitTimeMillis = new AtomicLong(0L);
    126    private volatile SwallowedExceptionListener swallowedExceptionListener = null;
    127
    128
    129    /**
    130     * Handles JMX registration (if required) and the initialization required for
    131     * monitoring.
    132     *
    133     * @param config        Pool configuration
    134     * @param jmxNameBase   The default base JMX name for the new pool unless
    135     *                      overridden by the config
    136     * @param jmxNamePrefix Prefix to be used for JMX name for the new pool
    137     */
    138    public BaseGenericObjectPool(final BaseObjectPoolConfig<T> config,
    139            final String jmxNameBase, final String jmxNamePrefix) {
    140        if (config.getJmxEnabled()) {
    141            this.objectName = jmxRegister(config, jmxNameBase, jmxNamePrefix);
    142        } else {
    143            this.objectName = null;
    144        }
    145
    146        // Populate the creation stack trace
    147        this.creationStackTrace = getStackTrace(new Exception());
    148
    149        // save the current TCCL (if any) to be used later by the evictor Thread
    150        final ClassLoader cl = Thread.currentThread().getContextClassLoader();
    151        if (cl == null) {
    152            factoryClassLoader = null;
    153        } else {
    154            factoryClassLoader = new WeakReference<>(cl);
    155        }
    156
    157        fairness = config.getFairness();
    158    }
    159
    160
    161    /**
    162     * Returns the maximum number of objects that can be allocated by the pool
    163     * (checked out to clients, or idle awaiting checkout) at a given time. When
    164     * negative, there is no limit to the number of objects that can be
    165     * managed by the pool at one time.
    166     *
    167     * @return the cap on the total number of object instances managed by the
    168     *         pool.
    169     *
    170     * @see #setMaxTotal
    171     */
    172    public final int getMaxTotal() {
    173        return maxTotal;
    174    }
    175
    176    /**
    177     * Sets the cap on the number of objects that can be allocated by the pool
    178     * (checked out to clients, or idle awaiting checkout) at a given time. Use
    179     * a negative value for no limit.
    180     *
    181     * @param maxTotal  The cap on the total number of object instances managed
    182     *                  by the pool. Negative values mean that there is no limit
    183     *                  to the number of objects allocated by the pool.
    184     *
    185     * @see #getMaxTotal
    186     */
    187    public final void setMaxTotal(final int maxTotal) {
    188        this.maxTotal = maxTotal;
    189    }
    190
    191    /**
    192     * Returns whether to block when the <code>borrowObject()</code> method is
    193     * invoked when the pool is exhausted (the maximum number of "active"
    194     * objects has been reached).
    195     *
    196     * @return <code>true</code> if <code>borrowObject()</code> should block
    197     *         when the pool is exhausted
    198     *
    199     * @see #setBlockWhenExhausted
    200     */
    201    public final boolean getBlockWhenExhausted() {
    202        return blockWhenExhausted;
    203    }
    204
    205    /**
    206     * Sets whether to block when the <code>borrowObject()</code> method is
    207     * invoked when the pool is exhausted (the maximum number of "active"
    208     * objects has been reached).
    209     *
    210     * @param blockWhenExhausted    <code>true</code> if
    211     *                              <code>borrowObject()</code> should block
    212     *                              when the pool is exhausted
    213     *
    214     * @see #getBlockWhenExhausted
    215     */
    216    public final void setBlockWhenExhausted(final boolean blockWhenExhausted) {
    217        this.blockWhenExhausted = blockWhenExhausted;
    218    }
    219
    220    /**
    221     * Initializes the receiver with the given configuration.
    222     *
    223     * @param config Initialization source.
    224     */
    225    protected void setConfig(final BaseObjectPoolConfig<T> config) {
    226        setLifo(config.getLifo());
    227        setMaxWaitMillis(config.getMaxWaitMillis());
    228        setBlockWhenExhausted(config.getBlockWhenExhausted());
    229        setTestOnCreate(config.getTestOnCreate());
    230        setTestOnBorrow(config.getTestOnBorrow());
    231        setTestOnReturn(config.getTestOnReturn());
    232        setTestWhileIdle(config.getTestWhileIdle());
    233        setNumTestsPerEvictionRun(config.getNumTestsPerEvictionRun());
    234        setMinEvictableIdleTimeMillis(config.getMinEvictableIdleTimeMillis());
    235        setTimeBetweenEvictionRunsMillis(config.getTimeBetweenEvictionRunsMillis());
    236        setSoftMinEvictableIdleTimeMillis(config.getSoftMinEvictableIdleTimeMillis());
    237        final EvictionPolicy<T> policy = config.getEvictionPolicy();
    238        if (policy == null) {
    239            // Use the class name (pre-2.6.0 compatible)
    240            setEvictionPolicyClassName(config.getEvictionPolicyClassName());
    241        } else {
    242            // Otherwise, use the class (2.6.0 feature)
    243            setEvictionPolicy(policy);
    244        }
    245        setEvictorShutdownTimeoutMillis(config.getEvictorShutdownTimeoutMillis());
    246    }
    247
    248    /**
    249     * Returns the maximum amount of time (in milliseconds) the
    250     * <code>borrowObject()</code> method should block before throwing an
    251     * exception when the pool is exhausted and
    252     * {@link #getBlockWhenExhausted} is true. When less than 0, the
    253     * <code>borrowObject()</code> method may block indefinitely.
    254     *
    255     * @return the maximum number of milliseconds <code>borrowObject()</code>
    256     *         will block.
    257     *
    258     * @see #setMaxWaitMillis
    259     * @see #setBlockWhenExhausted
    260     */
    261    public final long getMaxWaitMillis() {
    262        return maxWaitMillis;
    263    }
    264
    265    /**
    266     * Sets the maximum amount of time (in milliseconds) the
    267     * <code>borrowObject()</code> method should block before throwing an
    268     * exception when the pool is exhausted and
    269     * {@link #getBlockWhenExhausted} is true. When less than 0, the
    270     * <code>borrowObject()</code> method may block indefinitely.
    271     *
    272     * @param maxWaitMillis the maximum number of milliseconds
    273     *                      <code>borrowObject()</code> will block or negative
    274     *                      for indefinitely.
    275     *
    276     * @see #getMaxWaitMillis
    277     * @see #setBlockWhenExhausted
    278     */
    279    public final void setMaxWaitMillis(final long maxWaitMillis) {
    280        this.maxWaitMillis = maxWaitMillis;
    281    }
    282
    283    /**
    284     * Returns whether the pool has LIFO (last in, first out) behaviour with
    285     * respect to idle objects - always returning the most recently used object
    286     * from the pool, or as a FIFO (first in, first out) queue, where the pool
    287     * always returns the oldest object in the idle object pool.
    288     *
    289     * @return <code>true</code> if the pool is configured with LIFO behaviour
    290     *         or <code>false</code> if the pool is configured with FIFO
    291     *         behaviour
    292     *
    293     * @see #setLifo
    294     */
    295    public final boolean getLifo() {
    296        return lifo;
    297    }
    298
    299    /**
    300     * Returns whether or not the pool serves threads waiting to borrow objects fairly.
    301     * True means that waiting threads are served as if waiting in a FIFO queue.
    302     *
    303     * @return <code>true</code> if waiting threads are to be served
    304     *             by the pool in arrival order
    305     */
    306    public final boolean getFairness() {
    307        return fairness;
    308    }
    309
    310    /**
    311     * Sets whether the pool has LIFO (last in, first out) behaviour with
    312     * respect to idle objects - always returning the most recently used object
    313     * from the pool, or as a FIFO (first in, first out) queue, where the pool
    314     * always returns the oldest object in the idle object pool.
    315     *
    316     * @param lifo  <code>true</code> if the pool is to be configured with LIFO
    317     *              behaviour or <code>false</code> if the pool is to be
    318     *              configured with FIFO behaviour
    319     *
    320     * @see #getLifo()
    321     */
    322    public final void setLifo(final boolean lifo) {
    323        this.lifo = lifo;
    324    }
    325
    326    /**
    327     * Returns whether objects created for the pool will be validated before
    328     * being returned from the <code>borrowObject()</code> method. Validation is
    329     * performed by the <code>validateObject()</code> method of the factory
    330     * associated with the pool. If the object fails to validate, then
    331     * <code>borrowObject()</code> will fail.
    332     *
    333     * @return <code>true</code> if newly created objects are validated before
    334     *         being returned from the <code>borrowObject()</code> method
    335     *
    336     * @see #setTestOnCreate
    337     *
    338     * @since 2.2
    339     */
    340    public final boolean getTestOnCreate() {
    341        return testOnCreate;
    342    }
    343
    344    /**
    345     * Sets whether objects created for the pool will be validated before
    346     * being returned from the <code>borrowObject()</code> method. Validation is
    347     * performed by the <code>validateObject()</code> method of the factory
    348     * associated with the pool. If the object fails to validate, then
    349     * <code>borrowObject()</code> will fail.
    350     *
    351     * @param testOnCreate  <code>true</code> if newly created objects should be
    352     *                      validated before being returned from the
    353     *                      <code>borrowObject()</code> method
    354     *
    355     * @see #getTestOnCreate
    356     *
    357     * @since 2.2
    358     */
    359    public final void setTestOnCreate(final boolean testOnCreate) {
    360        this.testOnCreate = testOnCreate;
    361    }
    362
    363    /**
    364     * Returns whether objects borrowed from the pool will be validated before
    365     * being returned from the <code>borrowObject()</code> method. Validation is
    366     * performed by the <code>validateObject()</code> method of the factory
    367     * associated with the pool. If the object fails to validate, it will be
    368     * removed from the pool and destroyed, and a new attempt will be made to
    369     * borrow an object from the pool.
    370     *
    371     * @return <code>true</code> if objects are validated before being returned
    372     *         from the <code>borrowObject()</code> method
    373     *
    374     * @see #setTestOnBorrow
    375     */
    376    public final boolean getTestOnBorrow() {
    377        return testOnBorrow;
    378    }
    379
    380    /**
    381     * Sets whether objects borrowed from the pool will be validated before
    382     * being returned from the <code>borrowObject()</code> method. Validation is
    383     * performed by the <code>validateObject()</code> method of the factory
    384     * associated with the pool. If the object fails to validate, it will be
    385     * removed from the pool and destroyed, and a new attempt will be made to
    386     * borrow an object from the pool.
    387     *
    388     * @param testOnBorrow  <code>true</code> if objects should be validated
    389     *                      before being returned from the
    390     *                      <code>borrowObject()</code> method
    391     *
    392     * @see #getTestOnBorrow
    393     */
    394    public final void setTestOnBorrow(final boolean testOnBorrow) {
    395        this.testOnBorrow = testOnBorrow;
    396    }
    397
    398    /**
    399     * Returns whether objects borrowed from the pool will be validated when
    400     * they are returned to the pool via the <code>returnObject()</code> method.
    401     * Validation is performed by the <code>validateObject()</code> method of
    402     * the factory associated with the pool. Returning objects that fail validation
    403     * are destroyed rather then being returned the pool.
    404     *
    405     * @return <code>true</code> if objects are validated on return to
    406     *         the pool via the <code>returnObject()</code> method
    407     *
    408     * @see #setTestOnReturn
    409     */
    410    public final boolean getTestOnReturn() {
    411        return testOnReturn;
    412    }
    413
    414    /**
    415     * Sets whether objects borrowed from the pool will be validated when
    416     * they are returned to the pool via the <code>returnObject()</code> method.
    417     * Validation is performed by the <code>validateObject()</code> method of
    418     * the factory associated with the pool. Returning objects that fail validation
    419     * are destroyed rather then being returned the pool.
    420     *
    421     * @param testOnReturn <code>true</code> if objects are validated on
    422     *                     return to the pool via the
    423     *                     <code>returnObject()</code> method
    424     *
    425     * @see #getTestOnReturn
    426     */
    427    public final void setTestOnReturn(final boolean testOnReturn) {
    428        this.testOnReturn = testOnReturn;
    429    }
    430
    431    /**
    432     * Returns whether objects sitting idle in the pool will be validated by the
    433     * idle object evictor (if any - see
    434     * {@link #setTimeBetweenEvictionRunsMillis(long)}). Validation is performed
    435     * by the <code>validateObject()</code> method of the factory associated
    436     * with the pool. If the object fails to validate, it will be removed from
    437     * the pool and destroyed.
    438     *
    439     * @return <code>true</code> if objects will be validated by the evictor
    440     *
    441     * @see #setTestWhileIdle
    442     * @see #setTimeBetweenEvictionRunsMillis
    443     */
    444    public final boolean getTestWhileIdle() {
    445        return testWhileIdle;
    446    }
    447
    448    /**
    449     * Returns whether objects sitting idle in the pool will be validated by the
    450     * idle object evictor (if any - see
    451     * {@link #setTimeBetweenEvictionRunsMillis(long)}). Validation is performed
    452     * by the <code>validateObject()</code> method of the factory associated
    453     * with the pool. If the object fails to validate, it will be removed from
    454     * the pool and destroyed.  Note that setting this property has no effect
    455     * unless the idle object evictor is enabled by setting
    456     * <code>timeBetweenEvictionRunsMillis</code> to a positive value.
    457     *
    458     * @param testWhileIdle
    459     *            <code>true</code> so objects will be validated by the evictor
    460     *
    461     * @see #getTestWhileIdle
    462     * @see #setTimeBetweenEvictionRunsMillis
    463     */
    464    public final void setTestWhileIdle(final boolean testWhileIdle) {
    465        this.testWhileIdle = testWhileIdle;
    466    }
    467
    468    /**
    469     * Returns the number of milliseconds to sleep between runs of the idle
    470     * object evictor thread. When non-positive, no idle object evictor thread
    471     * will be run.
    472     *
    473     * @return number of milliseconds to sleep between evictor runs
    474     *
    475     * @see #setTimeBetweenEvictionRunsMillis
    476     */
    477    public final long getTimeBetweenEvictionRunsMillis() {
    478        return timeBetweenEvictionRunsMillis;
    479    }
    480
    481    /**
    482     * Sets the number of milliseconds to sleep between runs of the idle object evictor thread.
    483     * <ul>
    484     * <li>When positive, the idle object evictor thread starts.</li>
    485     * <li>When non-positive, no idle object evictor thread runs.</li>
    486     * </ul>
    487     *
    488     * @param timeBetweenEvictionRunsMillis
    489     *            number of milliseconds to sleep between evictor runs
    490     *
    491     * @see #getTimeBetweenEvictionRunsMillis
    492     */
    493    public final void setTimeBetweenEvictionRunsMillis(
    494            final long timeBetweenEvictionRunsMillis) {
    495        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
    496        startEvictor(timeBetweenEvictionRunsMillis);
    497    }
    498
    499    /**
    500     * Returns the maximum number of objects to examine during each run (if any)
    501     * of the idle object evictor thread. When positive, the number of tests
    502     * performed for a run will be the minimum of the configured value and the
    503     * number of idle instances in the pool. When negative, the number of tests
    504     * performed will be <code>ceil({@link #getNumIdle}/
    505     * abs({@link #getNumTestsPerEvictionRun}))</code> which means that when the
    506     * value is <code>-n</code> roughly one nth of the idle objects will be
    507     * tested per run.
    508     *
    509     * @return max number of objects to examine during each evictor run
    510     *
    511     * @see #setNumTestsPerEvictionRun
    512     * @see #setTimeBetweenEvictionRunsMillis
    513     */
    514    public final int getNumTestsPerEvictionRun() {
    515        return numTestsPerEvictionRun;
    516    }
    517
    518    /**
    519     * Sets the maximum number of objects to examine during each run (if any)
    520     * of the idle object evictor thread. When positive, the number of tests
    521     * performed for a run will be the minimum of the configured value and the
    522     * number of idle instances in the pool. When negative, the number of tests
    523     * performed will be <code>ceil({@link #getNumIdle}/
    524     * abs({@link #getNumTestsPerEvictionRun}))</code> which means that when the
    525     * value is <code>-n</code> roughly one nth of the idle objects will be
    526     * tested per run.
    527     *
    528     * @param numTestsPerEvictionRun
    529     *            max number of objects to examine during each evictor run
    530     *
    531     * @see #getNumTestsPerEvictionRun
    532     * @see #setTimeBetweenEvictionRunsMillis
    533     */
    534    public final void setNumTestsPerEvictionRun(final int numTestsPerEvictionRun) {
    535        this.numTestsPerEvictionRun = numTestsPerEvictionRun;
    536    }
    537
    538    /**
    539     * Returns the minimum amount of time an object may sit idle in the pool
    540     * before it is eligible for eviction by the idle object evictor (if any -
    541     * see {@link #setTimeBetweenEvictionRunsMillis(long)}). When non-positive,
    542     * no objects will be evicted from the pool due to idle time alone.
    543     *
    544     * @return minimum amount of time an object may sit idle in the pool before
    545     *         it is eligible for eviction
    546     *
    547     * @see #setMinEvictableIdleTimeMillis
    548     * @see #setTimeBetweenEvictionRunsMillis
    549     */
    550    public final long getMinEvictableIdleTimeMillis() {
    551        return minEvictableIdleTimeMillis;
    552    }
    553
    554    /**
    555     * Sets the minimum amount of time an object may sit idle in the pool
    556     * before it is eligible for eviction by the idle object evictor (if any -
    557     * see {@link #setTimeBetweenEvictionRunsMillis(long)}). When non-positive,
    558     * no objects will be evicted from the pool due to idle time alone.
    559     *
    560     * @param minEvictableIdleTimeMillis
    561     *            minimum amount of time an object may sit idle in the pool
    562     *            before it is eligible for eviction
    563     *
    564     * @see #getMinEvictableIdleTimeMillis
    565     * @see #setTimeBetweenEvictionRunsMillis
    566     */
    567    public final void setMinEvictableIdleTimeMillis(
    568            final long minEvictableIdleTimeMillis) {
    569        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
    570    }
    571
    572    /**
    573     * Returns the minimum amount of time an object may sit idle in the pool
    574     * before it is eligible for eviction by the idle object evictor (if any -
    575     * see {@link #setTimeBetweenEvictionRunsMillis(long)}),
    576     * with the extra condition that at least <code>minIdle</code> object
    577     * instances remain in the pool. This setting is overridden by
    578     * {@link #getMinEvictableIdleTimeMillis} (that is, if
    579     * {@link #getMinEvictableIdleTimeMillis} is positive, then
    580     * {@link #getSoftMinEvictableIdleTimeMillis} is ignored).
    581     *
    582     * @return minimum amount of time an object may sit idle in the pool before
    583     *         it is eligible for eviction if minIdle instances are available
    584     *
    585     * @see #setSoftMinEvictableIdleTimeMillis
    586     */
    587    public final long getSoftMinEvictableIdleTimeMillis() {
    588        return softMinEvictableIdleTimeMillis;
    589    }
    590
    591    /**
    592     * Sets the minimum amount of time an object may sit idle in the pool
    593     * before it is eligible for eviction by the idle object evictor (if any -
    594     * see {@link #setTimeBetweenEvictionRunsMillis(long)}),
    595     * with the extra condition that at least <code>minIdle</code> object
    596     * instances remain in the pool. This setting is overridden by
    597     * {@link #getMinEvictableIdleTimeMillis} (that is, if
    598     * {@link #getMinEvictableIdleTimeMillis} is positive, then
    599     * {@link #getSoftMinEvictableIdleTimeMillis} is ignored).
    600     *
    601     * @param softMinEvictableIdleTimeMillis
    602     *            minimum amount of time an object may sit idle in the pool
    603     *            before it is eligible for eviction if minIdle instances are
    604     *            available
    605     *
    606     * @see #getSoftMinEvictableIdleTimeMillis
    607     */
    608    public final void setSoftMinEvictableIdleTimeMillis(
    609            final long softMinEvictableIdleTimeMillis) {
    610        this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
    611    }
    612
    613    /**
    614     * Returns the name of the {@link EvictionPolicy} implementation that is
    615     * used by this pool.
    616     *
    617     * @return  The fully qualified class name of the {@link EvictionPolicy}
    618     *
    619     * @see #setEvictionPolicyClassName(String)
    620     */
    621    public final String getEvictionPolicyClassName() {
    622        return evictionPolicy.getClass().getName();
    623    }
    624
    625    /**
    626     * Sets the eviction policy for this pool.
    627     *
    628     * @param evictionPolicy
    629     *            the eviction policy for this pool.
    630     * @since 2.6.0
    631     */
    632    public void setEvictionPolicy(final EvictionPolicy<T> evictionPolicy) {
    633        this.evictionPolicy = evictionPolicy;
    634    }
    635
    636    /**
    637     * Sets the name of the {@link EvictionPolicy} implementation that is used by this pool. The Pool will attempt to
    638     * load the class using the given class loader. If that fails, use the class loader for the {@link EvictionPolicy}
    639     * interface.
    640     *
    641     * @param evictionPolicyClassName
    642     *            the fully qualified class name of the new eviction policy
    643     * @param classLoader
    644     *            the class loader to load the given {@code evictionPolicyClassName}.
    645     *
    646     * @see #getEvictionPolicyClassName()
    647     * @since 2.6.0 If loading the class using the given class loader fails, use the class loader for the
    648     *        {@link EvictionPolicy} interface.
    649     */
    650    public final void setEvictionPolicyClassName(final String evictionPolicyClassName, final ClassLoader classLoader) {
    651        // Getting epClass here and now best matches the caller's environment
    652        final Class<?> epClass = EvictionPolicy.class;
    653        final ClassLoader epClassLoader = epClass.getClassLoader();
    654        try {
    655            try {
    656                setEvictionPolicy(evictionPolicyClassName, classLoader);
    657            } catch (final ClassCastException | ClassNotFoundException e) {
    658                setEvictionPolicy(evictionPolicyClassName, epClassLoader);
    659            }
    660        } catch (final ClassCastException e) {
    661            throw new IllegalArgumentException("Class " + evictionPolicyClassName + " from class loaders [" +
    662                    classLoader + ", " + epClassLoader + "] do not implement " + EVICTION_POLICY_TYPE_NAME);
    663        } catch (final ClassNotFoundException | InstantiationException | IllegalAccessException |
    664                InvocationTargetException | NoSuchMethodException e) {
    665            final String exMessage = "Unable to create " + EVICTION_POLICY_TYPE_NAME + " instance of type " +
    666                    evictionPolicyClassName;
    667            throw new IllegalArgumentException(exMessage, e);
    668        }
    669    }
    670
    671    /**
    672     * Sets the eviction policy.
    673     *
    674     * @param className Eviction policy class name.
    675     * @param classLoader Load the class from this class loader.
    676     */
    677    @SuppressWarnings("unchecked")
    678    private void setEvictionPolicy(final String className, final ClassLoader classLoader)
    679            throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
    680        final Class<?> clazz = Class.forName(className, true, classLoader);
    681        final Object policy = clazz.getConstructor().newInstance();
    682        this.evictionPolicy = (EvictionPolicy<T>) policy;
    683    }
    684
    685    /**
    686     * Sets the name of the {@link EvictionPolicy} implementation that is used by this pool. The Pool will attempt to
    687     * load the class using the thread context class loader. If that fails, the use the class loader for the
    688     * {@link EvictionPolicy} interface.
    689     *
    690     * @param evictionPolicyClassName
    691     *            the fully qualified class name of the new eviction policy
    692     *
    693     * @see #getEvictionPolicyClassName()
    694     * @since 2.6.0 If loading the class using the thread context class loader fails, use the class loader for the
    695     *        {@link EvictionPolicy} interface.
    696     */
    697    public final void setEvictionPolicyClassName(final String evictionPolicyClassName) {
    698        setEvictionPolicyClassName(evictionPolicyClassName, Thread.currentThread().getContextClassLoader());
    699    }
    700
    701    /**
    702     * Gets the timeout that will be used when waiting for the Evictor to
    703     * shutdown if this pool is closed and it is the only pool still using the
    704     * the value for the Evictor.
    705     *
    706     * @return  The timeout in milliseconds that will be used while waiting for
    707     *          the Evictor to shut down.
    708     */
    709    public final long getEvictorShutdownTimeoutMillis() {
    710        return evictorShutdownTimeoutMillis;
    711    }
    712
    713    /**
    714     * Sets the timeout that will be used when waiting for the Evictor to
    715     * shutdown if this pool is closed and it is the only pool still using the
    716     * the value for the Evictor.
    717     *
    718     * @param evictorShutdownTimeoutMillis  the timeout in milliseconds that
    719     *                                      will be used while waiting for the
    720     *                                      Evictor to shut down.
    721     */
    722    public final void setEvictorShutdownTimeoutMillis(
    723            final long evictorShutdownTimeoutMillis) {
    724        this.evictorShutdownTimeoutMillis = evictorShutdownTimeoutMillis;
    725    }
    726
    727    /**
    728     * Closes the pool, destroys the remaining idle objects and, if registered
    729     * in JMX, deregisters it.
    730     */
    731    public abstract void close();
    732
    733    /**
    734     * Has this pool instance been closed.
    735     * @return <code>true</code> when this pool has been closed.
    736     */
    737    public final boolean isClosed() {
    738        return closed;
    739    }
    740
    741    /**
    742     * <p>Perform <code>numTests</code> idle object eviction tests, evicting
    743     * examined objects that meet the criteria for eviction. If
    744     * <code>testWhileIdle</code> is true, examined objects are validated
    745     * when visited (and removed if invalid); otherwise only objects that
    746     * have been idle for more than <code>minEvicableIdleTimeMillis</code>
    747     * are removed.</p>
    748     *
    749     * @throws Exception when there is a problem evicting idle objects.
    750     */
    751    public abstract void evict() throws Exception;
    752
    753    /**
    754     * Returns the {@link EvictionPolicy} defined for this pool.
    755     *
    756     * @return the eviction policy
    757     * @since 2.4
    758     * @since 2.6.0 Changed access from protected to public.
    759     */
    760    public EvictionPolicy<T> getEvictionPolicy() {
    761        return evictionPolicy;
    762    }
    763
    764    /**
    765     * Verifies that the pool is open.
    766     * @throws IllegalStateException if the pool is closed.
    767     */
    768    final void assertOpen() throws IllegalStateException {
    769        if (isClosed()) {
    770            throw new IllegalStateException("Pool not open");
    771        }
    772    }
    773
    774    /**
    775     * <p>Starts the evictor with the given delay. If there is an evictor
    776     * running when this method is called, it is stopped and replaced with a
    777     * new evictor with the specified delay.</p>
    778     *
    779     * <p>This method needs to be final, since it is called from a constructor.
    780     * See POOL-195.</p>
    781     *
    782     * @param delay time in milliseconds before start and between eviction runs
    783     */
    784    final void startEvictor(final long delay) {
    785        synchronized (evictionLock) {
    786            EvictionTimer.cancel(evictor, evictorShutdownTimeoutMillis, TimeUnit.MILLISECONDS);
    787            evictor = null;
    788            evictionIterator = null;
    789            if (delay > 0) {
    790                evictor = new Evictor();
    791                EvictionTimer.schedule(evictor, delay, delay);
    792            }
    793        }
    794    }
    795
    796    /**
    797     * Stops the evictor.
    798     */
    799    void stopEvictor() {
    800        startEvictor(-1L);
    801    }
    802    /**
    803     * Tries to ensure that the configured minimum number of idle instances are
    804     * available in the pool.
    805     * @throws Exception if an error occurs creating idle instances
    806     */
    807    abstract void ensureMinIdle() throws Exception;
    808
    809
    810    // Monitoring (primarily JMX) related methods
    811
    812    /**
    813     * Provides the name under which the pool has been registered with the
    814     * platform MBean server or <code>null</code> if the pool has not been
    815     * registered.
    816     * @return the JMX name
    817     */
    818    public final ObjectName getJmxName() {
    819        return objectName;
    820    }
    821
    822    /**
    823     * Provides the stack trace for the call that created this pool. JMX
    824     * registration may trigger a memory leak so it is important that pools are
    825     * deregistered when no longer used by calling the {@link #close()} method.
    826     * This method is provided to assist with identifying code that creates but
    827     * does not close it thereby creating a memory leak.
    828     * @return pool creation stack trace
    829     */
    830    public final String getCreationStackTrace() {
    831        return creationStackTrace;
    832    }
    833
    834    /**
    835     * The total number of objects successfully borrowed from this pool over the
    836     * lifetime of the pool.
    837     * @return the borrowed object count
    838     */
    839    public final long getBorrowedCount() {
    840        return borrowedCount.get();
    841    }
    842
    843    /**
    844     * The total number of objects returned to this pool over the lifetime of
    845     * the pool. This excludes attempts to return the same object multiple
    846     * times.
    847     * @return the returned object count
    848     */
    849    public final long getReturnedCount() {
    850        return returnedCount.get();
    851    }
    852
    853    /**
    854     * The total number of objects created for this pool over the lifetime of
    855     * the pool.
    856     * @return the created object count
    857     */
    858    public final long getCreatedCount() {
    859        return createdCount.get();
    860    }
    861
    862    /**
    863     * The total number of objects destroyed by this pool over the lifetime of
    864     * the pool.
    865     * @return the destroyed object count
    866     */
    867    public final long getDestroyedCount() {
    868        return destroyedCount.get();
    869    }
    870
    871    /**
    872     * The total number of objects destroyed by the evictor associated with this
    873     * pool over the lifetime of the pool.
    874     * @return the evictor destroyed object count
    875     */
    876    public final long getDestroyedByEvictorCount() {
    877        return destroyedByEvictorCount.get();
    878    }
    879
    880    /**
    881     * The total number of objects destroyed by this pool as a result of failing
    882     * validation during <code>borrowObject()</code> over the lifetime of the
    883     * pool.
    884     * @return validation destroyed object count
    885     */
    886    public final long getDestroyedByBorrowValidationCount() {
    887        return destroyedByBorrowValidationCount.get();
    888    }
    889
    890    /**
    891     * The mean time objects are active for based on the last {@link
    892     * #MEAN_TIMING_STATS_CACHE_SIZE} objects returned to the pool.
    893     * @return mean time an object has been checked out from the pool among
    894     * recently returned objects
    895     */
    896    public final long getMeanActiveTimeMillis() {
    897        return activeTimes.getMean();
    898    }
    899
    900    /**
    901     * The mean time objects are idle for based on the last {@link
    902     * #MEAN_TIMING_STATS_CACHE_SIZE} objects borrowed from the pool.
    903     * @return mean time an object has been idle in the pool among recently
    904     * borrowed objects
    905     */
    906    public final long getMeanIdleTimeMillis() {
    907        return idleTimes.getMean();
    908    }
    909
    910    /**
    911     * The mean time threads wait to borrow an object based on the last {@link
    912     * #MEAN_TIMING_STATS_CACHE_SIZE} objects borrowed from the pool.
    913     * @return mean time in milliseconds that a recently served thread has had
    914     * to wait to borrow an object from the pool
    915     */
    916    public final long getMeanBorrowWaitTimeMillis() {
    917        return waitTimes.getMean();
    918    }
    919
    920    /**
    921     * The maximum time a thread has waited to borrow objects from the pool.
    922     * @return maximum wait time in milliseconds since the pool was created
    923     */
    924    public final long getMaxBorrowWaitTimeMillis() {
    925        return maxBorrowWaitTimeMillis.get();
    926    }
    927
    928    /**
    929     * The number of instances currently idle in this pool.
    930     * @return count of instances available for checkout from the pool
    931     */
    932    public abstract int getNumIdle();
    933
    934    /**
    935     * The listener used (if any) to receive notifications of exceptions
    936     * unavoidably swallowed by the pool.
    937     *
    938     * @return The listener or <code>null</code> for no listener
    939     */
    940    public final SwallowedExceptionListener getSwallowedExceptionListener() {
    941        return swallowedExceptionListener;
    942    }
    943
    944    /**
    945     * The listener used (if any) to receive notifications of exceptions
    946     * unavoidably swallowed by the pool.
    947     *
    948     * @param swallowedExceptionListener    The listener or <code>null</code>
    949     *                                      for no listener
    950     */
    951    public final void setSwallowedExceptionListener(
    952            final SwallowedExceptionListener swallowedExceptionListener) {
    953        this.swallowedExceptionListener = swallowedExceptionListener;
    954    }
    955
    956    /**
    957     * Swallows an exception and notifies the configured listener for swallowed
    958     * exceptions queue.
    959     *
    960     * @param swallowException exception to be swallowed
    961     */
    962    final void swallowException(final Exception swallowException) {
    963        final SwallowedExceptionListener listener = getSwallowedExceptionListener();
    964
    965        if (listener == null) {
    966            return;
    967        }
    968
    969        try {
    970            listener.onSwallowException(swallowException);
    971        } catch (final VirtualMachineError e) {
    972            throw e;
    973        } catch (final Throwable t) {
    974            // Ignore. Enjoy the irony.
    975        }
    976    }
    977
    978    /**
    979     * Updates statistics after an object is borrowed from the pool.
    980     * @param p object borrowed from the pool
    981     * @param waitTime time (in milliseconds) that the borrowing thread had to wait
    982     */
    983    final void updateStatsBorrow(final PooledObject<T> p, final long waitTime) {
    984        borrowedCount.incrementAndGet();
    985        idleTimes.add(p.getIdleTimeMillis());
    986        waitTimes.add(waitTime);
    987
    988        // lock-free optimistic-locking maximum
    989        long currentMax;
    990        do {
    991            currentMax = maxBorrowWaitTimeMillis.get();
    992            if (currentMax >= waitTime) {
    993                break;
    994            }
    995        } while (!maxBorrowWaitTimeMillis.compareAndSet(currentMax, waitTime));
    996    }
    997
    998    /**
    999     * Updates statistics after an object is returned to the pool.
    1000     * @param activeTime the amount of time (in milliseconds) that the returning
    1001     * object was checked out
    1002     */
    1003    final void updateStatsReturn(final long activeTime) {
    1004        returnedCount.incrementAndGet();
    1005        activeTimes.add(activeTime);
    1006    }
    1007
    1008    /**
    1009     * Marks the object as returning to the pool.
    1010     * @param pooledObject instance to return to the keyed pool
    1011     */
    1012    protected void markReturningState(final PooledObject<T> pooledObject) {
    1013        synchronized(pooledObject) {
    1014            final PooledObjectState state = pooledObject.getState();
    1015            if (state != PooledObjectState.ALLOCATED) {
    1016                throw new IllegalStateException(
    1017                        "Object has already been returned to this pool or is invalid");
    1018            }
    1019            pooledObject.markReturning(); // Keep from being marked abandoned
    1020        }
    1021    }
    1022
    1023    /**
    1024     * Unregisters this pool's MBean.
    1025     */
    1026    final void jmxUnregister() {
    1027        if (objectName != null) {
    1028            try {
    1029                ManagementFactory.getPlatformMBeanServer().unregisterMBean(
    1030                        objectName);
    1031            } catch (final MBeanRegistrationException | InstanceNotFoundException e) {
    1032                swallowException(e);
    1033            }
    1034        }
    1035    }
    1036
    1037    /**
    1038     * Registers the pool with the platform MBean server.
    1039     * The registered name will be
    1040     * <code>jmxNameBase + jmxNamePrefix + i</code> where i is the least
    1041     * integer greater than or equal to 1 such that the name is not already
    1042     * registered. Swallows MBeanRegistrationException, NotCompliantMBeanException
    1043     * returning null.
    1044     *
    1045     * @param config Pool configuration
    1046     * @param jmxNameBase default base JMX name for this pool
    1047     * @param jmxNamePrefix name prefix
    1048     * @return registered ObjectName, null if registration fails
    1049     */
    1050    private ObjectName jmxRegister(final BaseObjectPoolConfig<T> config,
    1051            final String jmxNameBase, String jmxNamePrefix) {
    1052        ObjectName newObjectName = null;
    1053        final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
    1054        int i = 1;
    1055        boolean registered = false;
    1056        String base = config.getJmxNameBase();
    1057        if (base == null) {
    1058            base = jmxNameBase;
    1059        }
    1060        while (!registered) {
    1061            try {
    1062                ObjectName objName;
    1063                // Skip the numeric suffix for the first pool in case there is
    1064                // only one so the names are cleaner.
    1065                if (i == 1) {
    1066                    objName = new ObjectName(base + jmxNamePrefix);
    1067                } else {
    1068                    objName = new ObjectName(base + jmxNamePrefix + i);
    1069                }
    1070                mbs.registerMBean(this, objName);
    1071                newObjectName = objName;
    1072                registered = true;
    1073            } catch (final MalformedObjectNameException e) {
    1074                if (BaseObjectPoolConfig.DEFAULT_JMX_NAME_PREFIX.equals(
    1075                        jmxNamePrefix) && jmxNameBase.equals(base)) {
    1076                    // Shouldn't happen. Skip registration if it does.
    1077                    registered = true;
    1078                } else {
    1079                    // Must be an invalid name. Use the defaults instead.
    1080                    jmxNamePrefix =
    1081                            BaseObjectPoolConfig.DEFAULT_JMX_NAME_PREFIX;
    1082                    base = jmxNameBase;
    1083                }
    1084            } catch (final InstanceAlreadyExistsException e) {
    1085                // Increment the index and try again
    1086                i++;
    1087            } catch (final MBeanRegistrationException | NotCompliantMBeanException e) {
    1088                // Shouldn't happen. Skip registration if it does.
    1089                registered = true;
    1090            }
    1091        }
    1092        return newObjectName;
    1093    }
    1094
    1095    /**
    1096     * Gets the stack trace of an exception as a string.
    1097     * @param e exception to trace
    1098     * @return exception stack trace as a string
    1099     */
    1100    private String getStackTrace(final Exception e) {
    1101        // Need the exception in string form to prevent the retention of
    1102        // references to classes in the stack trace that could trigger a memory
    1103        // leak in a container environment.
    1104        final Writer w = new StringWriter();
    1105        final PrintWriter pw = new PrintWriter(w);
    1106        e.printStackTrace(pw);
    1107        return w.toString();
    1108    }
    1109
    1110    // Inner classes
    1111
    1112    /**
    1113     * The idle object evictor {@link TimerTask}.
    1114     *
    1115     * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis
    1116     */
    1117    class Evictor implements Runnable {
    1118
    1119        private ScheduledFuture<?> scheduledFuture;
    1120
    1121        /**
    1122         * Run pool maintenance.  Evict objects qualifying for eviction and then
    1123         * ensure that the minimum number of idle instances are available.
    1124         * Since the Timer that invokes Evictors is shared for all Pools but
    1125         * pools may exist in different class loaders, the Evictor ensures that
    1126         * any actions taken are under the class loader of the factory
    1127         * associated with the pool.
    1128         */
    1129        @Override
    1130        public void run() {
    1131            final ClassLoader savedClassLoader =
    1132                    Thread.currentThread().getContextClassLoader();
    1133            try {
    1134                if (factoryClassLoader != null) {
    1135                    // Set the class loader for the factory
    1136                    final ClassLoader cl = factoryClassLoader.get();
    1137                    if (cl == null) {
    1138                        // The pool has been dereferenced and the class loader
    1139                        // GC'd. Cancel this timer so the pool can be GC'd as
    1140                        // well.
    1141                        cancel();
    1142                        return;
    1143                    }
    1144                    Thread.currentThread().setContextClassLoader(cl);
    1145                }
    1146
    1147                // Evict from the pool
    1148                try {
    1149                    evict();
    1150                } catch(final Exception e) {
    1151                    swallowException(e);
    1152                } catch(final OutOfMemoryError oome) {
    1153                    // Log problem but give evictor thread a chance to continue
    1154                    // in case error is recoverable
    1155                    oome.printStackTrace(System.err);
    1156                }
    1157                // Re-create idle instances.
    1158                try {
    1159                    ensureMinIdle();
    1160                } catch (final Exception e) {
    1161                    swallowException(e);
    1162                }
    1163            } finally {
    1164                // Restore the previous CCL
    1165                Thread.currentThread().setContextClassLoader(savedClassLoader);
    1166            }
    1167        }
    1168
    1169
    1170        /**
    1171         * Sets the scheduled future.
    1172         *
    1173         * @param scheduledFuture the scheduled future.
    1174         */
    1175        void setScheduledFuture(final ScheduledFuture<?> scheduledFuture) {
    1176            this.scheduledFuture = scheduledFuture;
    1177        }
    1178
    1179
    1180        /**
    1181         * Cancels the scheduled future.
    1182         */
    1183        void cancel() {
    1184            scheduledFuture.cancel(false);
    1185        }
    1186    }
    1187
    1188    /**
    1189     * Maintains a cache of values for a single metric and reports
    1190     * statistics on the cached values.
    1191     */
    1192    private class StatsStore {
    1193
    1194        private final AtomicLong values[];
    1195        private final int size;
    1196        private int index;
    1197
    1198        /**
    1199         * Create a StatsStore with the given cache size.
    1200         *
    1201         * @param size number of values to maintain in the cache.
    1202         */
    1203        public StatsStore(final int size) {
    1204            this.size = size;
    1205            values = new AtomicLong[size];
    1206            for (int i = 0; i < size; i++) {
    1207                values[i] = new AtomicLong(-1);
    1208            }
    1209        }
    1210
    1211        /**
    1212         * Adds a value to the cache.  If the cache is full, one of the
    1213         * existing values is replaced by the new value.
    1214         *
    1215         * @param value new value to add to the cache.
    1216         */
    1217        public synchronized void add(final long value) {
    1218            values[index].set(value);
    1219            index++;
    1220            if (index == size) {
    1221                index = 0;
    1222            }
    1223        }
    1224
    1225        /**
    1226         * Returns the mean of the cached values.
    1227         *
    1228         * @return the mean of the cache, truncated to long
    1229         */
    1230        public long getMean() {
    1231            double result = 0;
    1232            int counter = 0;
    1233            for (int i = 0; i < size; i++) {
    1234                final long value = values[i].get();
    1235                if (value != -1) {
    1236                    counter++;
    1237                    result = result * ((counter - 1) / (double) counter) +
    1238                            value/(double) counter;
    1239                }
    1240            }
    1241            return (long) result;
    1242        }
    1243
    1244        @Override
    1245        public String toString() {
    1246            final StringBuilder builder = new StringBuilder();
    1247            builder.append("StatsStore [values=");
    1248            builder.append(Arrays.toString(values));
    1249            builder.append(", size=");
    1250            builder.append(size);
    1251            builder.append(", index=");
    1252            builder.append(index);
    1253            builder.append("]");
    1254            return builder.toString();
    1255        }
    1256    }
    1257
    1258    /**
    1259     * The idle object eviction iterator. Holds a reference to the idle objects.
    1260     */
    1261    class EvictionIterator implements Iterator<PooledObject<T>> {
    1262
    1263        private final Deque<PooledObject<T>> idleObjects;
    1264        private final Iterator<PooledObject<T>> idleObjectIterator;
    1265
    1266        /**
    1267         * Create an EvictionIterator for the provided idle instance deque.
    1268         * @param idleObjects underlying deque
    1269         */
    1270        EvictionIterator(final Deque<PooledObject<T>> idleObjects) {
    1271            this.idleObjects = idleObjects;
    1272
    1273            if (getLifo()) {
    1274                idleObjectIterator = idleObjects.descendingIterator();
    1275            } else {
    1276                idleObjectIterator = idleObjects.iterator();
    1277            }
    1278        }
    1279
    1280        /**
    1281         * Returns the idle object deque referenced by this iterator.
    1282         * @return the idle object deque
    1283         */
    1284        public Deque<PooledObject<T>> getIdleObjects() {
    1285            return idleObjects;
    1286        }
    1287
    1288        /** {@inheritDoc} */
    1289        @Override
    1290        public boolean hasNext() {
    1291            return idleObjectIterator.hasNext();
    1292        }
    1293
    1294        /** {@inheritDoc} */
    1295        @Override
    1296        public PooledObject<T> next() {
    1297            return idleObjectIterator.next();
    1298        }
    1299
    1300        /** {@inheritDoc} */
    1301        @Override
    1302        public void remove() {
    1303            idleObjectIterator.remove();
    1304        }
    1305
    1306    }
    1307
    1308    /**
    1309     * Wrapper for objects under management by the pool.
    1310     *
    1311     * GenericObjectPool and GenericKeyedObjectPool maintain references to all
    1312     * objects under management using maps keyed on the objects. This wrapper
    1313     * class ensures that objects can work as hash keys.
    1314     *
    1315     * @param <T> type of objects in the pool
    1316     */
    1317    static class IdentityWrapper<T> {
    1318        /** Wrapped object */
    1319        private final T instance;
    1320
    1321        /**
    1322         * Create a wrapper for an instance.
    1323         *
    1324         * @param instance object to wrap
    1325         */
    1326        public IdentityWrapper(final T instance) {
    1327            this.instance = instance;
    1328        }
    1329
    1330        @Override
    1331        public int hashCode() {
    1332            return System.identityHashCode(instance);
    1333        }
    1334
    1335        @Override
    1336        @SuppressWarnings("rawtypes")
    1337        public boolean equals(final Object other) {
    1338            return  other instanceof IdentityWrapper &&
    1339                    ((IdentityWrapper) other).instance == instance;
    1340        }
    1341
    1342        /**
    1343         * @return the wrapped object
    1344         */
    1345        public T getObject() {
    1346            return instance;
    1347        }
    1348
    1349        @Override
    1350        public String toString() {
    1351            final StringBuilder builder = new StringBuilder();
    1352            builder.append("IdentityWrapper [instance=");
    1353            builder.append(instance);
    1354            builder.append("]");
    1355            return builder.toString();
    1356        }
    1357    }
    1358
    1359    @Override
    1360    protected void toStringAppendFields(final StringBuilder builder) {
    1361        builder.append("maxTotal=");
    1362        builder.append(maxTotal);
    1363        builder.append(", blockWhenExhausted=");
    1364        builder.append(blockWhenExhausted);
    1365        builder.append(", maxWaitMillis=");
    1366        builder.append(maxWaitMillis);
    1367        builder.append(", lifo=");
    1368        builder.append(lifo);
    1369        builder.append(", fairness=");
    1370        builder.append(fairness);
    1371        builder.append(", testOnCreate=");
    1372        builder.append(testOnCreate);
    1373        builder.append(", testOnBorrow=");
    1374        builder.append(testOnBorrow);
    1375        builder.append(", testOnReturn=");
    1376        builder.append(testOnReturn);
    1377        builder.append(", testWhileIdle=");
    1378        builder.append(testWhileIdle);
    1379        builder.append(", timeBetweenEvictionRunsMillis=");
    1380        builder.append(timeBetweenEvictionRunsMillis);
    1381        builder.append(", numTestsPerEvictionRun=");
    1382        builder.append(numTestsPerEvictionRun);
    1383        builder.append(", minEvictableIdleTimeMillis=");
    1384        builder.append(minEvictableIdleTimeMillis);
    1385        builder.append(", softMinEvictableIdleTimeMillis=");
    1386        builder.append(softMinEvictableIdleTimeMillis);
    1387        builder.append(", evictionPolicy=");
    1388        builder.append(evictionPolicy);
    1389        builder.append(", closeLock=");
    1390        builder.append(closeLock);
    1391        builder.append(", closed=");
    1392        builder.append(closed);
    1393        builder.append(", evictionLock=");
    1394        builder.append(evictionLock);
    1395        builder.append(", evictor=");
    1396        builder.append(evictor);
    1397        builder.append(", evictionIterator=");
    1398        builder.append(evictionIterator);
    1399        builder.append(", factoryClassLoader=");
    1400        builder.append(factoryClassLoader);
    1401        builder.append(", oname=");
    1402        builder.append(objectName);
    1403        builder.append(", creationStackTrace=");
    1404        builder.append(creationStackTrace);
    1405        builder.append(", borrowedCount=");
    1406        builder.append(borrowedCount);
    1407        builder.append(", returnedCount=");
    1408        builder.append(returnedCount);
    1409        builder.append(", createdCount=");
    1410        builder.append(createdCount);
    1411        builder.append(", destroyedCount=");
    1412        builder.append(destroyedCount);
    1413        builder.append(", destroyedByEvictorCount=");
    1414        builder.append(destroyedByEvictorCount);
    1415        builder.append(", destroyedByBorrowValidationCount=");
    1416        builder.append(destroyedByBorrowValidationCount);
    1417        builder.append(", activeTimes=");
    1418        builder.append(activeTimes);
    1419        builder.append(", idleTimes=");
    1420        builder.append(idleTimes);
    1421        builder.append(", waitTimes=");
    1422        builder.append(waitTimes);
    1423        builder.append(", maxBorrowWaitTimeMillis=");
    1424        builder.append(maxBorrowWaitTimeMillis);
    1425        builder.append(", swallowedExceptionListener=");
    1426        builder.append(swallowedExceptionListener);
    1427    }
    1428
    1429
    1430}