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