package com.savantdegrees.gms.util; import org.apache.log4j.Logger; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import com.mchange.v2.c3p0.PooledDataSource; import com.mchange.v2.c3p0.C3P0Registry; import java.sql.SQLException; import java.lang.reflect.Field; import org.apache.catalina.loader.WebappClassLoader; public class C3POServletContextListener implements ServletContextListener{ private Logger log = Logger.getLogger(this.class); public void contextInitialized(ServletContextEvent contextEvent) { } public void contextDestroyed(ServletContextEvent contextEvent) { Set pooledDataSourceSet = (Set) C3P0Registry.getPooledDataSources(); for (PooledDataSource dataSource : pooledDataSourceSet) { try { dataSource.hardReset(); dataSource.close(); } catch (SQLException e) { // note - do not use log4j since it may have been unloaded by this point System.out.println("Unable to hard reset and close data source.", e); } } //Get a list of all classes loaded by the current webapp classloader WebappClassLoader classLoader = (WebappClassLoader) getClass().getClassLoader(); Field classLoaderClassesField = null; Class clazz = WebappClassLoader.class; while (classLoaderClassesField == null && clazz != null) { try { classLoaderClassesField = clazz.getDeclaredField("classes"); } catch (Exception exception) { //do nothing } clazz = clazz.getSuperclass(); } classLoaderClassesField.setAccessible(true); List classes = new ArrayList((Vector)classLoaderClassesField.get(classLoader)); for (Object o : classes) { Class c = (Class)o; //Make sure you identify only the packages that are holding references to the classloader. //Allowing this code to clear all static references will result in all sorts //of horrible things (like java segfaulting). if (c.getName().startsWith("com.savantdegrees")) { //Kill any static references within all these classes. for (Field f : c.getDeclaredFields()) { if (Modifier.isStatic(f.getModifiers()) && !Modifier.isFinal(f.getModifiers()) && !f.getType().isPrimitive()) { try { f.setAccessible(true); f.set(null, null); } catch (Exception exception) { //Log the exception } } } } } classes.clear(); System.out.println("SDASDA=========================="); System.out.println("CP30 contextDestroyed"); } }