001    
002    /*
003     * Copyright (C) 2011 Archie L. Cobbs. All rights reserved.
004     *
005     * $Id: ContextCleanupListener.java 50 2011-03-07 17:06:18Z archie.cobbs $
006     */
007    
008    package org.dellroad.stuff.servlet;
009    
010    import java.sql.Driver;
011    import java.sql.DriverManager;
012    import java.util.Enumeration;
013    
014    import javax.servlet.ServletContextEvent;
015    
016    import org.slf4j.Logger;
017    import org.slf4j.LoggerFactory;
018    import org.springframework.web.util.IntrospectorCleanupListener;
019    
020    /**
021     * Clears references that can cause container memory leaks on Web container class unloading.
022     *
023     * @see <a href="http://opensource.atlassian.com/confluence/spring/pages/viewpage.action?pageId=2669">Spring Wiki Discussion of
024     *      ClassLoader Memory Leaks</a>
025     * @since 1.0.49
026     */
027    public class ContextCleanupListener extends IntrospectorCleanupListener {
028    
029        protected final Logger log = LoggerFactory.getLogger(getClass());
030    
031        /**
032         * Unregisters any JDBC drivers registered under the current class loader after
033         * first invoking the superclass version of this method.
034         */
035        @Override
036        public void contextDestroyed(ServletContextEvent event) {
037            try {
038                super.contextDestroyed(event);
039                for (Enumeration<Driver> e = DriverManager.getDrivers(); e.hasMoreElements(); ) {
040                    Driver driver = e.nextElement();
041                    if (driver.getClass().getClassLoader() == getClass().getClassLoader()) {
042                        DriverManager.deregisterDriver(driver);
043                    }
044                }
045            } catch (Throwable e) {
046                log.error("exception cleaning up servlet context", e);
047            }
048        }
049    }