package com.revolsys.ui.web.servlet.listener; import java.beans.Introspector; import java.lang.management.ManagementFactory; import java.util.Enumeration; import java.util.Set; import javax.management.MBeanServer; import javax.management.ObjectName; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.apache.commons.beanutils.BeanUtilsBean; import org.apache.log4j.Logger; import org.springframework.beans.CachedIntrospectionResults; import org.springframework.beans.ClearCachedIntrospectionResults; import org.springframework.beans.factory.DisposableBean; import org.springframework.web.util.Log4jWebConfigurer; import com.revolsys.geometry.cs.epsg.EpsgCoordinateSystems; import com.revolsys.geometry.model.GeometryFactory; import com.revolsys.io.IoFactoryRegistry; import com.revolsys.logging.Logs; import com.revolsys.util.Property; public class ContextCleanupListener implements ServletContextListener { static void cleanupAttributes(final ServletContext servletContext) { @SuppressWarnings("rawtypes") final Enumeration attrNames = servletContext.getAttributeNames(); while (attrNames.hasMoreElements()) { final String attrName = (String)attrNames.nextElement(); if (attrName.startsWith("org.springframework.")) { final Object attrValue = servletContext.getAttribute(attrName); if (attrValue instanceof DisposableBean) { try { ((DisposableBean)attrValue).destroy(); } catch (final Throwable e) { System.err .println("Couldn't invoke destroy method of attribute with name '" + attrName + "'"); } } else { servletContext.removeAttribute(attrName); } } } } @Override public void contextDestroyed(final ServletContextEvent event) { final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); IoFactoryRegistry.clearInstance(); GeometryFactory.clear(); EpsgCoordinateSystems.clear(); cleanupAttributes(event.getServletContext()); BeanUtilsBean.setInstance(null); CachedIntrospectionResults.clearClassLoader(contextClassLoader); CachedIntrospectionResults.clearClassLoader(CachedIntrospectionResults.class.getClassLoader()); CachedIntrospectionResults.clearClassLoader(ClassLoader.getSystemClassLoader()); Introspector.flushCaches(); ClearCachedIntrospectionResults.clearCache(); Property.clearCache(); Logger.getRootLogger().removeAllAppenders(); Log4jWebConfigurer.shutdownLogging(event.getServletContext()); } @Override public void contextInitialized(final ServletContextEvent event) { Log4jWebConfigurer.initLogging(event.getServletContext()); CachedIntrospectionResults.acceptClassLoader(Thread.currentThread().getContextClassLoader()); } protected boolean isWebAppClassLoaderOrChild(ClassLoader classLoader) { final ClassLoader webAppClassLoader = getClass().getClassLoader(); while (classLoader != null) { if (classLoader == webAppClassLoader) { return true; } classLoader = classLoader.getParent(); } return false; } /** Unregister MBeans loaded by the web application class loader */ protected void unregisterMBeans() { try { final MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer(); final Set<ObjectName> allMBeanNames = mBeanServer.queryNames(new ObjectName("*:*"), null); for (final ObjectName mbeanName : allMBeanNames) { try { final ClassLoader mBeanClassLoader = mBeanServer.getClassLoaderFor(mbeanName); if (isWebAppClassLoaderOrChild(mBeanClassLoader)) { mBeanServer.unregisterMBean(mbeanName); } } catch (final Throwable e) { Logs.error(this, "Unable to deregister MBean" + mbeanName, e); } } } catch (final Throwable e) { Logs.error(this, "Unable to deregister MBeans", e); } } }