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