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