Index: java/org/apache/commons/pool/impl/EvictionTimer.java
===================================================================
--- java/org/apache/commons/pool/impl/EvictionTimer.java	(revision 0)
+++ java/org/apache/commons/pool/impl/EvictionTimer.java	(revision 0)
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.pool.impl;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+/**
+ * <p>
+ * Provides a shared idle object eviction timer for all pools. This class wraps
+ * the standard {@link Timer} and keeps track of how many pools are using it.
+ * If no pools are using the timer, it is cancelled. This prevents a thread
+ * being left running which, in application server environments, can lead to
+ * memory leads and/or prevent applications from shutting down or reloading
+ * cleanly.
+ * </p>
+ * <p>
+ * This calls has package scope to prevent its inclusion in the pool public API.
+ * The class declaration below should *not* be changed to public.
+ * </p> 
+ */
+class EvictionTimer {
+    private static Timer _timer;
+    private static int _usageCount;
+    
+    private EvictionTimer() {
+        // Hide the default constuctor
+    }
+    
+    /**
+     * Add the specified eviction task to the timer. Tasks that are added with a
+     * call to this method *must* call {@link #cancel(TimerTask)} to cancel the
+     * task to prevent memory and/or thread leaks in application server
+     * environments.
+     * @param task      Task to be scheduled
+     * @param delay     Delay in milliseconds before task is executed
+     * @param period    Time in milliseconds between executions
+     */
+    static synchronized void schedule(TimerTask task, long delay, long period) {
+        if (null == _timer) {
+            _timer = new Timer();
+        }
+        _usageCount++;
+        _timer.schedule(task, delay, period);
+    }
+    
+    /**
+     * Remove the specified eviction task from the timer.
+     * @param task      Task to be scheduled
+     * @param delay     Delay in milliseconds before task is executed
+     * @param period    Time in milliseconds between executions
+     */
+    static synchronized void cancel(TimerTask task) {
+        task.cancel();
+        _usageCount--;
+        if (_usageCount == 0) {
+            _timer.cancel();
+            _timer = null;
+        }
+    }
+}

Property changes on: java\org\apache\commons\pool\impl\EvictionTimer.java
___________________________________________________________________
Name: svn:eol-style
   + native

Index: java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java
===================================================================
--- java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java	(revision 600642)
+++ java/org/apache/commons/pool/impl/GenericKeyedObjectPool.java	(working copy)
@@ -1244,10 +1244,7 @@
                 _evictionKeyCursor.close();
                 _evictionKeyCursor = null;
             }
-            if (null != _evictor) {
-                _evictor.cancel();
-                _evictor = null;
-            }
+            startEvictor(-1L);
         }
     }
 
@@ -1491,12 +1488,12 @@
      */
     protected synchronized void startEvictor(long delay) {
         if(null != _evictor) {
-            _evictor.cancel();
+            EvictionTimer.cancel(_evictor);
             _evictor = null;
         }
         if(delay > 0) {
             _evictor = new Evictor();
-            GenericObjectPool.EVICTION_TIMER.schedule(_evictor, delay, delay);
+            EvictionTimer.schedule(_evictor, delay, delay);
         }
     }
 
@@ -1850,11 +1847,6 @@
     private Evictor _evictor = null;
 
     /**
-     * Position in the _pool where the _evictor last stopped.
-     */
-    private int _evictLastIndex = -1;
-    
-    /**
      * A cursorable list of my pools.
      * @see GenericKeyedObjectPool.Evictor#run
      */
Index: java/org/apache/commons/pool/impl/GenericObjectPool.java
===================================================================
--- java/org/apache/commons/pool/impl/GenericObjectPool.java	(revision 600642)
+++ java/org/apache/commons/pool/impl/GenericObjectPool.java	(working copy)
@@ -19,9 +19,6 @@
 
 import java.util.Iterator;
 import java.util.NoSuchElementException;
-import java.util.LinkedList;
-import java.util.ListIterator;
-import java.util.Timer;
 import java.util.TimerTask;
 
 import org.apache.commons.pool.BaseObjectPool;
@@ -281,13 +278,6 @@
      */
     public static final long DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS = -1;
 
-    //--- package constants -------------------------------------------
-
-    /**
-     * Idle object evition Timer. Shared between all {@link GenericObjectPool}s and {@link GenericKeyedObjectPool} s.
-     */
-    static final Timer EVICTION_TIMER = new Timer(true);
-
     //--- constructors -----------------------------------------------
 
     /**
@@ -1094,7 +1084,6 @@
     public synchronized void evict() throws Exception {
         assertOpen();
         if(!_pool.isEmpty()) {
-            ListIterator iter;
             if (null == _evictionCursor) {
                 _evictionCursor = (_pool.cursor(_lifo ? _pool.size() : 0));
             }  
@@ -1200,12 +1189,12 @@
      */
     protected synchronized void startEvictor(long delay) {
         if(null != _evictor) {
-            _evictor.cancel();
+            EvictionTimer.cancel(_evictor);
             _evictor = null;
         }
         if(delay > 0) {
             _evictor = new Evictor();
-            EVICTION_TIMER.schedule(_evictor, delay, delay);
+            EvictionTimer.schedule(_evictor, delay, delay);
         }
     }
 
