    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.util.ArrayList;
    024import java.util.Iterator;
    025import java.util.LinkedList;
    026import java.util.List;
    027import java.util.TimerTask;
    028import java.util.concurrent.atomic.AtomicLong;
    029
    030import javax.management.InstanceAlreadyExistsException;
    031import javax.management.InstanceNotFoundException;
    032import javax.management.MBeanRegistrationException;
    033import javax.management.MBeanServer;
    034import javax.management.MalformedObjectNameException;
    035import javax.management.NotCompliantMBeanException;
    036import javax.management.ObjectName;
    037
    038import org.apache.commons.pool2.PooledObject;
    039import org.apache.commons.pool2.SwallowedExceptionListener;
    040
    041/**
    042 * Base class that provides common functionality for {@link GenericObjectPool}
    043 * and {@link GenericKeyedObjectPool}. The primary reason this class exists is
    044 * reduce code duplication between the two pool implementations.
    045 *
    046 * @param <T> Type of element pooled in this pool.
    047 *
    048 * This class is intended to be thread-safe.
    049 *
    050 * @version $Revision: $
    051 *
    052 * @since 2.0
    053 */
    054public abstract class BaseGenericObjectPool<T> {
    055
    056    // Constants
    057    /**
    058     * The size of the caches used to store historical data for some attributes
    059     * so that rolling means may be calculated.
    060     */
    061    public static final int MEAN_TIMING_STATS_CACHE_SIZE = 100;
    062
    063    // Configuration attributes
    064    private volatile int maxTotal =
    065            GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL;
    066    private volatile boolean blockWhenExhausted =
    067            BaseObjectPoolConfig.DEFAULT_BLOCK_WHEN_EXHAUSTED;
    068    private volatile long maxWaitMillis =
    069            BaseObjectPoolConfig.DEFAULT_MAX_WAIT_MILLIS;
    070    private volatile boolean lifo = BaseObjectPoolConfig.DEFAULT_LIFO;
    071    private volatile boolean testOnBorrow =
    072            BaseObjectPoolConfig.DEFAULT_TEST_ON_BORROW;
    073    private volatile boolean testOnReturn =
    074            BaseObjectPoolConfig.DEFAULT_TEST_ON_RETURN;
    075    private volatile boolean testWhileIdle =
    076            BaseObjectPoolConfig.DEFAULT_TEST_WHILE_IDLE;
    077    private volatile long timeBetweenEvictionRunsMillis =
    078            BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
    079    private volatile int numTestsPerEvictionRun =
    080            BaseObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
    081    private volatile long minEvictableIdleTimeMillis =
    082            BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
    083    private volatile long softMinEvictableIdleTimeMillis =
    084            BaseObjectPoolConfig.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
    085    private volatile EvictionPolicy<T> evictionPolicy;
    086
    087
    088    // Internal (primarily state) attributes
    089    final Object closeLock = new Object();
    090    volatile boolean closed = false;
    091    final Object evictionLock = new Object();
    092    private Evictor evictor = null; // @GuardedBy("evictionLock")
    093    Iterator<PooledObject<T>> evictionIterator = null; // @GuardedBy("evictionLock")
    094    /*
    095     * Class loader for evictor thread to use since in a J2EE or similar
    096     * environment the context class loader for the evictor thread may have
    097     * visibility of the correct factory. See POOL-161.
    098     */
    099    private final ClassLoader factoryClassLoader;
    100
    101
    102    // Monitoring (primarily JMX) attributes
    103    private final ObjectName oname;
    104    private final String creationStackTrace;
    105    private final AtomicLong borrowedCount = new AtomicLong(0);
    106    private final AtomicLong returnedCount = new AtomicLong(0);
    107    final AtomicLong createdCount = new AtomicLong(0);
    108    final AtomicLong destroyedCount = new AtomicLong(0);
    109    final AtomicLong destroyedByEvictorCount = new AtomicLong(0);
    110    final AtomicLong destroyedByBorrowValidationCount = new AtomicLong(0);
    111    private final LinkedList<Long> activeTimes = new LinkedList<Long>(); // @GuardedBy("activeTimes") - except in initStats()
    112    private final LinkedList<Long> idleTimes = new LinkedList<Long>(); // @GuardedBy("activeTimes") - except in initStats()
    113    private final LinkedList<Long> waitTimes = new LinkedList<Long>(); // @GuardedBy("activeTimes") - except in initStats()
    114    private final Object maxBorrowWaitTimeMillisLock = new Object();
    115    private volatile long maxBorrowWaitTimeMillis = 0; // @GuardedBy("maxBorrowWaitTimeMillisLock")
    116    private SwallowedExceptionListener swallowedExceptionListener = null;
    117
    118
    119    /**
    120     * Handles JMX registration (if required) and the initialization required for
    121     * monitoring.
    122     *
    123     * @param config        Pool configuration
    124     * @param jmxNameBase   The default base JMX name for the new pool unless
    125     *                      overridden by the config
    126     * @param jmxNamePrefix Prefix to be used for JMX name for the new pool
    127     */
    128    public BaseGenericObjectPool(BaseObjectPoolConfig config,
    129            String jmxNameBase, String jmxNamePrefix) {
    130        if (config.getJmxEnabled()) {
    131            this.oname = jmxRegister(config, jmxNameBase, jmxNamePrefix);
    132        } else {
    133            this.oname = null;
    134        }
    135
    136        // Populate the creation stack trace
    137        this.creationStackTrace = getStackTrace(new Exception());
    138
    139        // save the current CCL to be used later by the evictor Thread
    140        factoryClassLoader = Thread.currentThread().getContextClassLoader();
    141
    142        // Initialise the attributes used to record rolling averages
    143        initStats();
    144    }
    145
    146
    147    /**
    148     * Returns the maximum number of objects that can be allocated by the pool
    149     * (checked out to clients, or idle awaiting checkout) at a given time. When
    150     * negative, there is no limit to the number of objects that can be
    151     * managed by the pool at one time.
    152     *
    153     * @return the cap on the total number of object instances managed by the
    154     *         pool.
    155     *
    156     * @see #setMaxTotal
    157     */
    158    public final int getMaxTotal() {
    159        return maxTotal;
    160    }
    161
    162    /**
    163     * Sets the cap on the number of objects that can be allocated by the pool
    164     * (checked out to clients, or idle awaiting checkout) at a given time. Use
    165     * a negative value for no limit.
    166     *
    167     * @param maxTotal  The cap on the total number of object instances managed
    168     *                  by the pool. Negative values mean that there is no limit
    169     *                  to the number of objects allocated by the pool.
    170     *
    171     * @see #getMaxTotal
    172     */
    173    public final void setMaxTotal(int maxTotal) {
    174        this.maxTotal = maxTotal;
    175    }
    176
    177    /**
    178     * Returns whether to block when the <code>borrowObject()</code> method is
    179     * invoked when the pool is exhausted (the maximum number of "active"
    180     * objects has been reached).
    181     *
    182     * @return <code>true</code> if <code>borrowObject()</code> should block
    183     *         when the pool is exhausted
    184     *
    185     * @see #setBlockWhenExhausted
    186     */
    187    public final boolean getBlockWhenExhausted() {
    188        return blockWhenExhausted;
    189    }
    190
    191    /**
    192     * Sets 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     * @param blockWhenExhausted    <code>true</code> if
    197     *                              <code>borrowObject()</code> should block
    198     *                              when the pool is exhausted
    199     *
    200     * @see #getBlockWhenExhausted
    201     */
    202    public final void setBlockWhenExhausted(boolean blockWhenExhausted) {
    203        this.blockWhenExhausted = blockWhenExhausted;
    204    }
    205
    206    /**
    207     * Returns the maximum amount of time (in milliseconds) the
    208     * <code>borrowObject()</code> method should block before throwing an
    209     * exception when the pool is exhausted and
    210     * {@link #getBlockWhenExhausted} is true. When less than 0, the
    211     * <code>borrowObject()</code> method may block indefinitely.
    212     *
    213     * @return the maximum number of milliseconds <code>borrowObject()</code>
    214     *         will block.
    215     *
    216     * @see #setMaxWaitMillis
    217     * @see #setBlockWhenExhausted
    218     */
    219    public final long getMaxWaitMillis() {
    220        return maxWaitMillis;
    221    }
    222
    223    /**
    224     * Sets the maximum amount of time (in milliseconds) the
    225     * <code>borrowObject()</code> method should block before throwing an
    226     * exception when the pool is exhausted and
    227     * {@link #getBlockWhenExhausted} is true. When less than 0, the
    228     * <code>borrowObject()</code> method may block indefinitely.
    229     *
    230     * @param maxWaitMillis the maximum number of milliseconds
    231     *                      <code>borrowObject()</code> will block or negative
    232     *                      for indefinitely.
    233     *
    234     * @see #getMaxWaitMillis
    235     * @see #setBlockWhenExhausted
    236     */
    237    public final void setMaxWaitMillis(long maxWaitMillis) {
    238        this.maxWaitMillis = maxWaitMillis;
    239    }
    240
    241    /**
    242     * Returns whether the pool has LIFO (last in, first out) behaviour with
    243     * respect to idle objects - always returning the most recently used object
    244     * from the pool, or as a FIFO (first in, first out) queue, where the pool
    245     * always returns the oldest object in the idle object pool.
    246     *
    247     * @return <code>true</code> if the pool is configured with LIFO behaviour
    248     *         or <code>false</code> if the pool is configured with FIFO
    249     *         behaviour
    250     *
    251     * @see #setLifo
    252     */
    253    public final boolean getLifo() {
    254        return lifo;
    255    }
    256
    257    /**
    258     * Sets whether the pool has LIFO (last in, first out) behaviour with
    259     * respect to idle objects - always returning the most recently used object
    260     * from the pool, or as a FIFO (first in, first out) queue, where the pool
    261     * always returns the oldest object in the idle object pool.
    262     *
    263     * @param lifo  <code>true</code> if the pool is to be configured with LIFO
    264     *              behaviour or <code>false</code> if the pool is to be
    265     *              configured with FIFO behaviour
    266     *
    267     * @see #getLifo()
    268     */
    269    public final void setLifo(boolean lifo) {
    270        this.lifo = lifo;
    271    }
    272
    273    /**
    274     * Returns whether objects borrowed from the pool will be validated before
    275     * being returned from the <code>borrowObject()</code> method. Validation is
    276     * performed by the <code>validateObject()</code> method of the factory
    277     * associated with the pool. If the object fails to validate, it will be
    278     * removed from the pool and destroyed, and a new attempt will be made to
    279     * borrow an object from the pool.
    280     *
    281     * @return <code>true</code> if objects are validated before being returned
    282     *         from the <code>borrowObject()</code> method
    283     *
    284     * @see #setTestOnBorrow
    285     */
    286    public final boolean getTestOnBorrow() {
    287        return testOnBorrow;
    288    }
    289
    290    /**
    291     * Sets whether objects borrowed from the pool will be validated before
    292     * being returned from the <code>borrowObject()</code> method. Validation is
    293     * performed by the <code>validateObject()</code> method of the factory
    294     * associated with the pool. If the object fails to validate, it will be
    295     * removed from the pool and destroyed, and a new attempt will be made to
    296     * borrow an object from the pool.
    297     *
    298     * @param testOnBorrow  <code>true</code> if objects should be validated
    299     *                      before being returned from the
    300     *                      <code>borrowObject()</code> method
    301     *
    302     * @see #getTestOnBorrow
    303     */
    304    public final void setTestOnBorrow(boolean testOnBorrow) {
    305        this.testOnBorrow = testOnBorrow;
    306    }
    307
    308    /**
    309     * Returns whether objects borrowed from the pool will be validated when
    310     * they are returned to the pool via the <code>returnObject()</code> method.
    311     * Validation is performed by the <code>validateObject()</code> method of
    312     * the factory associated with the pool. Returning objects that fail validation
    313     * are destroyed rather then being returned the pool.
    314     *
    315     * @return <code>true</code> if objects are validated on return to
    316     *         the pool via the <code>returnObject()</code> method
    317     *
    318     * @see #setTestOnReturn
    319     */
    320    public final boolean getTestOnReturn() {
    321        return testOnReturn;
    322    }
    323
    324    /**
    325     * Sets whether objects borrowed from the pool will be validated when
    326     * they are returned to the pool via the <code>returnObject()</code> method.
    327     * Validation is performed by the <code>validateObject()</code> method of
    328     * the factory associated with the pool. Returning objects that fail validation
    329     * are destroyed rather then being returned the pool.
    330     *
    331     * @param testOnReturn <code>true</code> if objects are validated on
    332     *                     return to the pool via the
    333     *                     <code>returnObject()</code> method
    334     *
    335     * @see #getTestOnReturn
    336     */
    337    public final void setTestOnReturn(boolean testOnReturn) {
    338        this.testOnReturn = testOnReturn;
    339    }
    340
    341    /**
    342     * Returns whether objects sitting idle in the pool will be validated by the
    343     * idle object evictor (if any - see
    344     * {@link #setTimeBetweenEvictionRunsMillis(long)}). Validation is performed
    345     * by the <code>validateObject()</code> method of the factory associated
    346     * with the pool. If the object fails to validate, it will be removed from
    347     * the pool and destroyed.
    348     *
    349     * @return <code>true</code> if objects will be validated by the evictor
    350     *
    351     * @see #setTestWhileIdle
    352     * @see #setTimeBetweenEvictionRunsMillis
    353     */
    354    public final boolean getTestWhileIdle() {
    355        return testWhileIdle;
    356    }
    357
    358    /**
    359     * Returns whether objects sitting idle in the pool will be validated by the
    360     * idle object evictor (if any - see
    361     * {@link #setTimeBetweenEvictionRunsMillis(long)}). Validation is performed
    362     * by the <code>validateObject()</code> method of the factory associated
    363     * with the pool. If the object fails to validate, it will be removed from
    364     * the pool and destroyed.  Note that setting this property has no effect
    365     * unless the idle object evictor is enabled by setting
    366     * <code>timeBetweenEvictionRunsMillis</code> to a positive value.
    367     *
    368     * @param testWhileIdle
    369     *            <code>true</code> so objects will be validated by the evictor
    370     *
    371     * @see #getTestWhileIdle
    372     * @see #setTimeBetweenEvictionRunsMillis
    373     */
    374    public final void setTestWhileIdle(boolean testWhileIdle) {
    375        this.testWhileIdle = testWhileIdle;
    376    }
    377
    378    /**
    379     * Returns the number of milliseconds to sleep between runs of the idle
    380     * object evictor thread. When non-positive, no idle object evictor thread
    381     * will be run.
    382     *
    383     * @return number of milliseconds to sleep between evictor runs
    384     *
    385     * @see #setTimeBetweenEvictionRunsMillis
    386     */
    387    public final long getTimeBetweenEvictionRunsMillis() {
    388        return timeBetweenEvictionRunsMillis;
    389    }
    390
    391    /**
    392     * Sets the number of milliseconds to sleep between runs of the idle
    393     * object evictor thread. When non-positive, no idle object evictor thread
    394     * will be run.
    395     *
    396     * @param timeBetweenEvictionRunsMillis
    397     *            number of milliseconds to sleep between evictor runs
    398     *
    399     * @see #getTimeBetweenEvictionRunsMillis
    400     */
    401    public final void setTimeBetweenEvictionRunsMillis(
    402            long timeBetweenEvictionRunsMillis) {
    403        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
    404        startEvictor(timeBetweenEvictionRunsMillis);
    405    }
    406
    407    /**
    408     * Returns the maximum number of objects to examine during each run (if any)
    409     * of the idle object evictor thread. When positive, the number of tests
    410     * performed for a run will be the minimum of the configured value and the
    411     * number of idle instances in the pool. When negative, the number of tests
    412     * performed will be <code>ceil({@link #getNumIdle}/
    413     * abs({@link #getNumTestsPerEvictionRun})) which means that when the value
    414     * is <code>-n</code> roughly one nth of the idle objects will be tested per
    415     * run.
    416     *
    417     * @return max number of objects to examine during each evictor run
    418     *
    419     * @see #setNumTestsPerEvictionRun
    420     * @see #setTimeBetweenEvictionRunsMillis
    421     */
    422    public final int getNumTestsPerEvictionRun() {
    423        return numTestsPerEvictionRun;
    424    }
    425
    426    /**
    427     * Sets the maximum number of objects to examine during each run (if any)
    428     * of the idle object evictor thread. When positive, the number of tests
    429     * performed for a run will be the minimum of the configured value and the
    430     * number of idle instances in the pool. When negative, the number of tests
    431     * performed will be <code>ceil({@link #getNumIdle}/
    432     * abs({@link #getNumTestsPerEvictionRun})) which means that when the value
    433     * is <code>-n</code> roughly one nth of the idle objects will be tested per
    434     * run.
    435     *
    436     * @param numTestsPerEvictionRun
    437     *            max number of objects to examine during each evictor run
    438     *
    439     * @see #getNumTestsPerEvictionRun
    440     * @see #setTimeBetweenEvictionRunsMillis
    441     */
    442    public final void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
    443        this.numTestsPerEvictionRun = numTestsPerEvictionRun;
    444    }
    445
    446    /**
    447     * Returns the minimum amount of time an object may sit idle in the pool
    448     * before it is eligible for eviction by the idle object evictor (if any -
    449     * see {@link #setTimeBetweenEvictionRunsMillis(long)}). When non-positive,
    450     * no objects will be evicted from the pool due to idle time alone.
    451     *
    452     * @return minimum amount of time an object may sit idle in the pool before
    453     *         it is eligible for eviction
    454     *
    455     * @see #setMinEvictableIdleTimeMillis
    456     * @see #setTimeBetweenEvictionRunsMillis
    457     */
    458    public final long getMinEvictableIdleTimeMillis() {
    459        return minEvictableIdleTimeMillis;
    460    }
    461
    462    /**
    463     * Sets the minimum amount of time an object may sit idle in the pool
    464     * before it is eligible for eviction by the idle object evictor (if any -
    465     * see {@link #setTimeBetweenEvictionRunsMillis(long)}). When non-positive,
    466     * no objects will be evicted from the pool due to idle time alone.
    467     *
    468     * @param minEvictableIdleTimeMillis
    469     *            minimum amount of time an object may sit idle in the pool
    470     *            before it is eligible for eviction
    471     *
    472     * @see #getMinEvictableIdleTimeMillis
    473     * @see #setTimeBetweenEvictionRunsMillis
    474     */
    475    public final void setMinEvictableIdleTimeMillis(
    476            long minEvictableIdleTimeMillis) {
    477        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
    478    }
    479
    480    /**
    481     * Returns the minimum amount of time an object may sit idle in the pool
    482     * before it is eligible for eviction by the idle object evictor (if any -
    483     * see {@link #setTimeBetweenEvictionRunsMillis(long)}),
    484     * with the extra condition that at least <code>minIdle</code> object
    485     * instances remain in the pool. This setting is overridden by
    486     * {@link #getMinEvictableIdleTimeMillis} (that is, if
    487     * {@link #getMinEvictableIdleTimeMillis} is positive, then
    488     * {@link #getSoftMinEvictableIdleTimeMillis} is ignored).
    489     *
    490     * @return minimum amount of time an object may sit idle in the pool before
    491     *         it is eligible for eviction if minIdle instances are available
    492     *
    493     * @see #setSoftMinEvictableIdleTimeMillis
    494     */
    495    public final long getSoftMinEvictableIdleTimeMillis() {
    496        return softMinEvictableIdleTimeMillis;
    497    }
    498
    499    /**
    500     * Sets the minimum amount of time an object may sit idle in the pool
    501     * before it is eligible for eviction by the idle object evictor (if any -
    502     * see {@link #setTimeBetweenEvictionRunsMillis(long)}),
    503     * with the extra condition that at least <code>minIdle</code> object
    504     * instances remain in the pool. This setting is overridden by
    505     * {@link #getMinEvictableIdleTimeMillis} (that is, if
    506     * {@link #getMinEvictableIdleTimeMillis} is positive, then
    507     * {@link #getSoftMinEvictableIdleTimeMillis} is ignored).
    508     *
    509     * @param softMinEvictableIdleTimeMillis
    510     *            minimum amount of time an object may sit idle in the pool
    511     *            before it is eligible for eviction if minIdle instances are
    512     *            available
    513     *
    514     * @see #getSoftMinEvictableIdleTimeMillis
    515     */
    516    public final void setSoftMinEvictableIdleTimeMillis(
    517            long softMinEvictableIdleTimeMillis) {
    518        this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
    519    }
    520
    521    /**
    522     * Returns the name of the {@link EvictionPolicy} implementation that is
    523     * used by this pool.
    524     *
    525     * @return  The fully qualified class name of the {@link EvictionPolicy}
    526     *
    527     * @see #setEvictionPolicyClassName(String)
    528     */
    529    public final String getEvictionPolicyClassName() {
    530        return evictionPolicy.getClass().getName();
    531    }
    532
    533    /**
    534     * Sets the name of the {@link EvictionPolicy} implementation that is
    535     * used by this pool.
    536     *
    537     * @param evictionPolicyClassName   the fully qualified class name of the
    538     *                                  new eviction policy
    539     *
    540     * @see #getEvictionPolicyClassName()
    541     */
    542    public final void setEvictionPolicyClassName(
    543            String evictionPolicyClassName) {
    544        try {
    545            Class<?> clazz = Class.forName(evictionPolicyClassName);
    546            Object policy = clazz.newInstance();
    547            if (policy instanceof EvictionPolicy<?>) {
    548                @SuppressWarnings("unchecked") // safe, because we just checked the class
    549                EvictionPolicy<T> evicPolicy = (EvictionPolicy<T>) policy;
    550                this.evictionPolicy = evicPolicy;
    551            }
    552        } catch (ClassNotFoundException e) {
    553            throw new IllegalArgumentException(
    554                    "Unable to create EvictionPolicy instance of type " +
    555                    evictionPolicyClassName, e);
    556        } catch (InstantiationException e) {
    557            throw new IllegalArgumentException(
    558                    "Unable to create EvictionPolicy instance of type " +
    559                    evictionPolicyClassName, e);
    560        } catch (IllegalAccessException e) {
    561            throw new IllegalArgumentException(
    562                    "Unable to create EvictionPolicy instance of type " +
    563                    evictionPolicyClassName, e);
    564        }
    565    }
    566
    567
    568    /**
    569     * Closes the pool, destroys the remaining idle objects and, if registered
    570     * in JMX, deregisters it.
    571     */
    572    public abstract void close();
    573
    574    /**
    575     * Has this pool instance been closed.
    576     * @return <code>true</code> when this pool has been closed.
    577     */
    578    public final boolean isClosed() {
    579        return closed;
    580    }
    581
    582    /**
    583     * <p>Perform <code>numTests</code> idle object eviction tests, evicting
    584     * examined objects that meet the criteria for eviction. If
    585     * <code>testWhileIdle</code> is true, examined objects are validated
    586     * when visited (and removed if invalid); otherwise only objects that
    587     * have been idle for more than <code>minEvicableIdleTimeMillis</code>
    588     * are removed.</p>
    589     *
    590     * @throws Exception when there is a problem evicting idle objects.
    591     */
    592    public abstract void evict() throws Exception;
    593
    594    /**
    595     * Returns the {@link EvictionPolicy} defined for this pool.
    596     * @return the eviction policy
    597     */
    598    final EvictionPolicy<T> getEvictionPolicy() {
    599        return evictionPolicy;
    600    }
    601
    602    /**
    603     * Verifies that the pool is open.
    604     * @throws IllegalStateException if the pool is closed.
    605     */
    606    final void assertOpen() throws IllegalStateException {
    607        if (isClosed()) {
    608            throw new IllegalStateException("Pool not open");
    609        }
    610    }
    611
    612    /**
    613     * <p>Starts the evictor with the given delay. If there is an evictor
    614     * running when this method is called, it is stopped and replaced with a
    615     * new evictor with the specified delay.</p>
    616     *
    617     * <p>This method needs to be final, since it is called from a constructor.
    618     * See POOL-195.</p>
    619     *
    620     * @param delay time in milliseconds before start and between eviction runs
    621     */
    622    final void startEvictor(long delay) {
    623        synchronized (evictionLock) {
    624            if (null != evictor) {
    625                EvictionTimer.cancel(evictor);
    626                evictor = null;
    627                evictionIterator = null;
    628            }
    629            if (delay > 0) {
    630                evictor = new Evictor();
    631                EvictionTimer.schedule(evictor, delay, delay);
    632            }
    633        }
    634    }
    635
    636    /**
    637     * Tries to ensure that the configured minimum number of idle instances are
    638     * available in the pool.
    639     * @throws Exception if an error occurs creating idle instances
    640     */
    641    abstract void ensureMinIdle() throws Exception;
    642
    643
    644    // Monitoring (primarily JMX) related methods
    645
    646    /**
    647     * Provides the name under which the pool has been registered with the
    648     * platform MBean server or <code>null</code> if the pool has not been
    649     * registered.
    650     * @return the JMX name
    651     */
    652    public final ObjectName getJmxName() {
    653        return oname;
    654    }
    655
    656    /**
    657     * Provides the stack trace for the call that created this pool. JMX
    658     * registration may trigger a memory leak so it is important that pools are
    659     * deregistered when no longer used by calling the {@link #close()} method.
    660     * This method is provided to assist with identifying code that creates but
    661     * does not close it thereby creating a memory leak.
    662     * @return pool creation stack trace
    663     */
    664    public final String getCreationStackTrace() {
    665        return creationStackTrace;
    666    }
    667
    668    /**
    669     * The total number of objects successfully borrowed from this pool over the
    670     * lifetime of the pool.
    671     * @return the borrowed object count
    672     */
    673    public final long getBorrowedCount() {
    674        return borrowedCount.get();
    675    }
    676
    677    /**
    678     * The total number of objects returned to this pool over the lifetime of
    679     * the pool. This excludes attempts to return the same object multiple
    680     * times.
    681     * @return the returned object count
    682     */
    683    public final long getReturnedCount() {
    684        return returnedCount.get();
    685    }
    686
    687    /**
    688     * The total number of objects created for this pool over the lifetime of
    689     * the pool.
    690     * @return the created object count
    691     */
    692    public final long getCreatedCount() {
    693        return createdCount.get();
    694    }
    695
    696    /**
    697     * The total number of objects destroyed by this pool over the lifetime of
    698     * the pool.
    699     * @return the destroyed object count
    700     */
    701    public final long getDestroyedCount() {
    702        return destroyedCount.get();
    703    }
    704
    705    /**
    706     * The total number of objects destroyed by the evictor associated with this
    707     * pool over the lifetime of the pool.
    708     * @return the evictor destroyed object count
    709     */
    710    public final long getDestroyedByEvictorCount() {
    711        return destroyedByEvictorCount.get();
    712    }
    713
    714    /**
    715     * The total number of objects destroyed by this pool as a result of failing
    716     * validation during <code>borrowObject()</code> over the lifetime of the
    717     * pool.
    718     * @return validation destroyed object count
    719     */
    720    public final long getDestroyedByBorrowValidationCount() {
    721        return destroyedByBorrowValidationCount.get();
    722    }
    723
    724    /**
    725     * The mean time objects are active for based on the last {@link
    726     * #MEAN_TIMING_STATS_CACHE_SIZE} objects returned to the pool.
    727     * @return mean time an object has been checked out from the pool among
    728     * recently returned objects
    729     */
    730    public final long getMeanActiveTimeMillis() {
    731        return getMeanFromStatsCache(activeTimes);
    732    }
    733
    734    /**
    735     * The mean time objects are idle for based on the last {@link
    736     * #MEAN_TIMING_STATS_CACHE_SIZE} objects borrowed from the pool.
    737     * @return mean time an object has been idle in the pool among recently
    738     * borrowed objects
    739     */
    740    public final long getMeanIdleTimeMillis() {
    741        return getMeanFromStatsCache(idleTimes);
    742    }
    743
    744    /**
    745     * The mean time threads wait to borrow an object based on the last {@link
    746     * #MEAN_TIMING_STATS_CACHE_SIZE} objects borrowed from the pool.
    747     * @return mean time in milliseconds that a recently served thread has had
    748     * to wait to borrow an object from the pool
    749     */
    750    public final long getMeanBorrowWaitTimeMillis() {
    751        return getMeanFromStatsCache(waitTimes);
    752    }
    753
    754    /**
    755     * The maximum time a thread has waited to borrow objects from the pool.
    756     * @return maximum wait time in milliseconds since the pool was created
    757     */
    758    public final long getMaxBorrowWaitTimeMillis() {
    759        return maxBorrowWaitTimeMillis;
    760    }
    761
    762    /**
    763     * The number of instances currently idle in this pool.
    764     * @return count of instances available for checkout from the pool
    765     */
    766    public abstract int getNumIdle();
    767
    768    /**
    769     * The listener used (if any) to receive notifications of exceptions
    770     * unavoidably swallowed by the pool.
    771     *
    772     * @return The listener or <code>null</code> for no listener
    773     */
    774    public final SwallowedExceptionListener getSwallowedExceptionListener() {
    775        return swallowedExceptionListener;
    776    }
    777
    778    /**
    779     * The listener used (if any) to receive notifications of exceptions
    780     * unavoidably swallowed by the pool.
    781     *
    782     * @param swallowedExceptionListener    The listener or <code>null</code>
    783     *                                      for no listener
    784     */
    785    public final void setSwallowedExceptionListener(
    786            SwallowedExceptionListener swallowedExceptionListener) {
    787        this.swallowedExceptionListener = swallowedExceptionListener;
    788    }
    789
    790    /**
    791     * Swallows an exception and notifies the configured listener for swallowed
    792     * exceptions queue.
    793     *
    794     * @param e exception to be swallowed
    795     */
    796    final void swallowException(Exception e) {
    797        SwallowedExceptionListener listener = getSwallowedExceptionListener();
    798
    799        if (listener == null) {
    800            return;
    801        }
    802
    803        try {
    804            listener.onSwallowException(e);
    805        } catch (OutOfMemoryError oome) {
    806            throw oome;
    807        } catch (VirtualMachineError vme) {
    808            throw vme;
    809        } catch (Throwable t) {
    810            // Ignore. Enjoy the irony.
    811        }
    812    }
    813
    814    /**
    815     * Updates statistics after an object is borrowed from the pool.
    816     * @param p object borrowed from the pool
    817     * @param waitTime time (in milliseconds) that the borrowing thread had to wait
    818     */
    819    final void updateStatsBorrow(PooledObject<T> p, long waitTime) {
    820        borrowedCount.incrementAndGet();
    821        synchronized (idleTimes) {
    822            idleTimes.add(Long.valueOf(p.getIdleTimeMillis()));
    823            idleTimes.poll();
    824        }
    825        synchronized (waitTimes) {
    826            waitTimes.add(Long.valueOf(waitTime));
    827            waitTimes.poll();
    828        }
    829        synchronized (maxBorrowWaitTimeMillisLock) {
    830            if (waitTime > maxBorrowWaitTimeMillis) {
    831                maxBorrowWaitTimeMillis = waitTime;
    832            }
    833        }
    834    }
    835
    836    /**
    837     * Updates statistics after an object is returned to the pool.
    838     * @param activeTime the amount of time (in milliseconds) that the returning
    839     * object was checked out
    840     */
    841    final void updateStatsReturn(long activeTime) {
    842        returnedCount.incrementAndGet();
    843        synchronized (activeTimes) {
    844            activeTimes.add(Long.valueOf(activeTime));
    845            activeTimes.poll();
    846        }
    847    }
    848
    849    /**
    850     * Unregisters this pool's MBean.
    851     */
    852    final void jmxUnregister() {
    853        if (oname != null) {
    854            try {
    855                ManagementFactory.getPlatformMBeanServer().unregisterMBean(
    856                        oname);
    857            } catch (MBeanRegistrationException e) {
    858                swallowException(e);
    859            } catch (InstanceNotFoundException e) {
    860                swallowException(e);
    861            }
    862        }
    863    }
    864
    865    /**
    866     * Registers the pool with the platform MBean server.
    867     * The registered name will be
    868     * <code>jmxNameBase + jmxNamePrefix + i</code> where i is the least
    869     * integer greater than or equal to 1 such that the name is not already
    870     * registered. Swallows MBeanRegistrationException, NotCompliantMBeanException
    871     * returning null.
    872     *
    873     * @param config Pool configuration
    874     * @param jmxNameBase default base JMX name for this pool
    875     * @param jmxNamePrefix name prefix
    876     * @return registered ObjectName, null if registration fails
    877     */
    878    private ObjectName jmxRegister(BaseObjectPoolConfig config,
    879            String jmxNameBase, String jmxNamePrefix) {
    880        ObjectName objectName = null;
    881        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
    882        int i = 1;
    883        boolean registered = false;
    884        String base = config.getJmxNameBase();
    885        if (base == null) {
    886            base = jmxNameBase;
    887        }
    888        while (!registered) {
    889            try {
    890                ObjectName objName;
    891                // Skip the numeric suffix for the first pool in case there is
    892                // only one so the names are cleaner.
    893                if (i == 1) {
    894                    objName = new ObjectName(base + jmxNamePrefix);
    895                } else {
    896                    objName = new ObjectName(base + jmxNamePrefix + i);
    897                }
    898                mbs.registerMBean(this, objName);
    899                objectName = objName;
    900                registered = true;
    901            } catch (MalformedObjectNameException e) {
    902                if (BaseObjectPoolConfig.DEFAULT_JMX_NAME_PREFIX.equals(
    903                        jmxNamePrefix) && jmxNameBase.equals(base)) {
    904                    // Shouldn't happen. Skip registration if it does.
    905                    registered = true;
    906                } else {
    907                    // Must be an invalid name. Use the defaults instead.
    908                    jmxNamePrefix =
    909                            BaseObjectPoolConfig.DEFAULT_JMX_NAME_PREFIX;
    910                    base = jmxNameBase;
    911                }
    912            } catch (InstanceAlreadyExistsException e) {
    913                // Increment the index and try again
    914                i++;
    915            } catch (MBeanRegistrationException e) {
    916                // Shouldn't happen. Skip registration if it does.
    917                registered = true;
    918            } catch (NotCompliantMBeanException e) {
    919                // Shouldn't happen. Skip registration if it does.
    920                registered = true;
    921            }
    922        }
    923        return objectName;
    924    }
    925
    926    /**
    927     * Gets the stack trace of an exception as a string.
    928     * @param e exception to trace
    929     * @return exception stack trace as a string
    930     */
    931    private String getStackTrace(Exception e) {
    932        // Need the exception in string form to prevent the retention of
    933        // references to classes in the stack trace that could trigger a memory
    934        // leak in a container environment.
    935        Writer w = new StringWriter();
    936        PrintWriter pw = new PrintWriter(w);
    937        e.printStackTrace(pw);
    938        return w.toString();
    939    }
    940
    941    /**
    942     * Returns the greatest integer less than ore equal to the arithmetic mean
    943     * of the entries in <code>cache,</code> acquiring and holding the argument's
    944     * monitor while making a local copy.
    945     * @param cache list containing entries to analyze
    946     * @return truncated arithmetic mean
    947     */
    948    private long getMeanFromStatsCache(LinkedList<Long> cache) {
    949        List<Long> times = new ArrayList<Long>(MEAN_TIMING_STATS_CACHE_SIZE);
    950        synchronized (cache) {
    951            times.addAll(cache);
    952        }
    953        double result = 0;
    954        int counter = 0;
    955        Iterator<Long> iter = times.iterator();
    956        while (iter.hasNext()) {
    957            Long time = iter.next();
    958            if (time != null) {
    959                counter++;
    960                result = result * ((counter - 1) / (double) counter) +
    961                        time.longValue()/(double) counter;
    962            }
    963        }
    964        return (long) result;
    965    }
    966
    967    /**
    968     * Initializes pool statistics.
    969     */
    970    private void initStats() {
    971        for (int i = 0; i < MEAN_TIMING_STATS_CACHE_SIZE; i++) {
    972            activeTimes.add(null);
    973            idleTimes.add(null);
    974            waitTimes.add(null);
    975        }
    976    }
    977
    978
    979    // Inner classes
    980
    981    /**
    982     * The idle object evictor {@link TimerTask}.
    983     *
    984     * @see GenericKeyedObjectPool#setTimeBetweenEvictionRunsMillis
    985     */
    986    class Evictor extends TimerTask {
    987        /**
    988         * Run pool maintenance.  Evict objects qualifying for eviction and then
    989         * ensure that the minimum number of idle instances are available.
    990         * Since the Timer that invokes Evictors is shared for all Pools but
    991         * pools may exist in different class loaders, the Evictor ensures that
    992         * any actions taken are under the class loader of the factory
    993         * associated with the pool.
    994         */
    995        @Override
    996        public void run() {
    997            ClassLoader savedClassLoader =
    998                    Thread.currentThread().getContextClassLoader();
    999            try {
    1000                // Set the class loader for the factory
    1001                Thread.currentThread().setContextClassLoader(
    1002                        factoryClassLoader);
    1003
    1004                // Evict from the pool
    1005                try {
    1006                    evict();
    1007                } catch(Exception e) {
    1008                    swallowException(e);
    1009                } catch(OutOfMemoryError oome) {
    1010                    // Log problem but give evictor thread a chance to continue
    1011                    // in case error is recoverable
    1012                    oome.printStackTrace(System.err);
    1013                }
    1014                // Re-create idle instances.
    1015                try {
    1016                    ensureMinIdle();
    1017                } catch (Exception e) {
    1018                    swallowException(e);
    1019                }
    1020            } finally {
    1021                // Restore the previous CCL
    1022                Thread.currentThread().setContextClassLoader(savedClassLoader);
    1023            }
    1024        }
    1025    }
    1026}