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