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