Fixing glassfish 4.1.1 memory leak (again)

It's again annoying to restart the glassfish instance again and again because it's out of memory.
In the current version glassfish 4.1.1 I am using the same technique to free the leaked memory as before. (Read here glassfish-memory-leak.wiki).
Instead of reporting further bugs, Iam publishing the code of my ContextListener. It's not a pretty code but a working one.
package de.bb.glassfish.memory.leak;

import java.beans.Introspector;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.WeakHashMap;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import de.bb.util.LRUCache;

public class ContextListener implements ServletContextListener {

    private final static Logger LOG = Logger.getLogger(ContextListener.class);


    public void contextDestroyed(ServletContextEvent sce) {
        // LOG.setLevel(Level.DEBUG);
        fixAppserver();
        LOG.info("flushing bean caches");
        Introspector.flushCaches();
        LOG.info("clearing ResourceBundle cache");
        ResourceBundle.clearCache();
        LOG.info("closing LOG");
        LogManager.shutdown();
        LOG.info("stopping LRUCache");
        LRUCache.shutDown();

        // NOTE: YOU CAN'T INVOKE EJBs HERE - APP IS SHUTDOWN!!!
    }

    public void contextInitialized(final ServletContextEvent sce) {
    }

    private void fixAppserver() {
        final Thread threads[] = getThreads();
        final HashSet<ClassLoader> gfClassLoaders = isGlassfish(threads);
        if (!gfClassLoaders.isEmpty()) {
            fixGlassfish(threads, gfClassLoaders);
        }
    }

    /**
     * Get all threads. (really? There are threads not inside thread groups!!!)
     * 
     * @return an array with all threads.
     */
    private Thread[] getThreads() {
        for (int size = 200;; size += size) {
            final Thread[] threads = new Thread[size];
            // start searching from the topmost thread group to search all threads
            ThreadGroup root = Thread.currentThread().getThreadGroup();
            while (root.getParent() != null) {
                root = root.getParent();
            }
            int n = root.enumerate(threads);
            if (n < size) {
                final Thread[] result = new Thread[n];
                System.arraycopy(threads, 0, result, 0, n);
                return result;
            }
        }
    }

    /**
     * Fill a collection with the typical glassfish class loaders.
     * 
     * @param threads
     *            all found threads.
     * @return
     */
    private HashSet<ClassLoader> isGlassfish(final Thread[] threads) {
        final HashSet<ClassLoader> result = new HashSet<ClassLoader>();
        for (final Thread thread : threads) {
            if (thread == null)
                break;
            for (ClassLoader cl = thread.getClass().getClassLoader(); cl != null; cl = cl.getParent()) {
                final String clName = cl.getClass().getName();
                if (clName.endsWith("ClassLoaderJava5")) {
                    result.add(cl);
                }
            }
        }
        return result;
    }

    /**
     * Apply cleanup fixes for the broken glassfish server.
     * 
     * @param threads
     * @param gfClassLoaders
     */
    private void fixGlassfish(final Thread[] threads, final HashSet<ClassLoader> gfClassLoaders) {
        try {
            // remove only my class loader
            LOG.info("fixing glassfish");

            // determine class loader urls to identify my own classloader
            final Set<Object> myUrlSet = new HashSet<Object>();
            ClassLoader myClassLoader = this.getClass().getClassLoader();
            for (ClassLoader cl = myClassLoader; cl != null; cl = cl.getParent()) {
                if (cl.getClass().getName().indexOf("Ear") >= 0) {
                    myClassLoader = cl;

                    final Set<Object> set = (Set<Object>) getMember(myClassLoader, "urlSet");
                    myUrlSet.addAll(set);
                }
            }

            fixWebBundleClassloader(myUrlSet, myClassLoader);

            fixJavaBug7199818(myUrlSet, myClassLoader);

            fixGlassfishBugWSIT1655(myUrlSet, myClassLoader);

            fixGlassfishBug17468(myUrlSet, myClassLoader);

            fixGlassfishBugxxxx(myUrlSet, myClassLoader);

            fixResourceManager();

            for (Thread thread : threads) {
                if (thread == null)
                    break;
                try {
                    cleanThread(thread, myClassLoader, myUrlSet);
                } catch (Exception ex) {
                    LOG.error(ex, ex);
                }
            }

            fixORB();

            fixClassCopier(myUrlSet, myClassLoader);

            fixWebserviceEndpoints(myUrlSet, myClassLoader);

            fixInjector();

            fixObjectCopierImpl(myUrlSet, myClassLoader);

            fixClassInfoCache(myUrlSet, myClassLoader);

            fixRepositoryClassToRep(gfClassLoaders, myUrlSet, myClassLoader);

            fixJavaFaces(myUrlSet, myClassLoader);

        } catch (Exception ex2) {
            LOG.error(ex2, ex2);
        }
    }

    /**
     * This fix causes an exception during application shutdown, but without there is a memory leak
     * @param myUrlSet
     * @param myClassLoader
     */
    private void fixJavaFaces(Set<Object> myUrlSet, ClassLoader myClassLoader) {
        try {
            final Class<?> factoryFinder = Class.forName("javax.faces.FactoryFinder");
            if (factoryFinder == null)
                return;

            final Object currentThreadToServletContext = getMember(null, factoryFinder, "FACTORIES_CACHE");
            if (currentThreadToServletContext == null)
                return;

            final Map applicationMap = (Map) getMember(currentThreadToServletContext, "applicationMap");
            if (applicationMap == null)
                return;

            for (Iterator<Entry> i = applicationMap.entrySet().iterator(); i.hasNext();) {
                final Entry e = i.next();
                final Object o = getMember(e.getKey(), "cl");
                if (o instanceof ClassLoader) {
                    ClassLoader cl = (ClassLoader) o;
                    if (refersToMyEar(cl, myClassLoader, myUrlSet)) {
                        LOG.info("fix JavaFaces factory cache - remove: " + e.getValue());
                        i.remove();
                    }
                }
            }
        } catch (Exception ex) {
            LOG.error(ex, ex);
        }

        try {
            final Class factoryContext = Class.forName("javax.faces.context.FacesContext");
            if (factoryContext == null)
                return;

            final Map initContextServletContext = (Map) getMember(null, factoryContext, "initContextServletContext");

            if (initContextServletContext == null)
                return;

            for (Iterator<Entry> i = initContextServletContext.entrySet().iterator(); i.hasNext();) {
                final Entry e = i.next();
                final Object o = getMember(e.getValue(), "context.context.wmInfo._appClassLoader");
                if (o instanceof ClassLoader) {
                    final ClassLoader cl = (ClassLoader) o;
                    if (refersToMyEar(cl, myClassLoader, myUrlSet)) {
                        LOG.info("fix JavaFaces initContextServletContext - remove: " + e.getValue());
                        i.remove();
                    }
                }
            }
        } catch (Exception ex) {
            LOG.error(ex, ex);
        }

    }

    private void fixRepositoryClassToRep(final HashSet<ClassLoader> gfClassLoaders, final Set<Object> myUrlSet,
            ClassLoader myClassLoader) {
        try {
            for (final ClassLoader cl : gfClassLoaders) {
                final Collection<Class<?>> classes = (Collection<Class<?>>) getMember(cl, "classes");
                for (Class<?> c : classes) {
                    if (c.getName().equals("com.sun.corba.ee.impl.util.RepositoryId")) {
                        LOG.info("clearing com.sun.corba.ee.impl.util.RepositoryId:classToRepStr");
                        final Map<?, ?> classToRepStr = (Map<?, ?>) getMember(null, c, "classToRepStr");
                        classToRepStr.clear();

                        final Map<?, ?> repStrToClass = (Map<?, ?>) getMember(null, c, "repStrToClass");
                        repStrToClass.toString();
                        for (Iterator<?> i = repStrToClass.values().iterator(); i.hasNext();) {
                            Class<?> aClass = (Class<?>) i.next();
                            if (aClass != null && refersToMyEar(aClass.getClassLoader(), myClassLoader, myUrlSet)) {
                                LOG.info("remove repStrToClass for: " + aClass);
                                i.remove();
                            }
                        }

                    } else if (c.getName().equals("com.sun.corba.ee.impl.copyobject.ReflectObjectCopierImpl")) {
                        final Object ccf = getMember(null, c, "ccf");
                        clearCcf(myUrlSet, myClassLoader, ccf);

                    }
                }
            }
        } catch (Exception ex) {
            LOG.error(ex, ex);
        }
    }

    /**
     * Clean the ClassInfoCache for items refering to our class loader.
     * @param myUrlSet
     * @param myClassLoader
     */
    private void fixClassInfoCache(final Set<Object> myUrlSet, ClassLoader myClassLoader) {
        try {
            // class com.sun.corba.ee.impl.orbutil.ClassInfoCache
            final Map<?, ?> classData = (Map<?, ?>) getMember(null,
                    Class.forName("com.sun.corba.ee.impl.orbutil.ClassInfoCache"), "classData");
            for (Iterator<?> i = classData.keySet().iterator(); i.hasNext();) {
                Class<?> aClass = (Class<?>) i.next();
                if (aClass != null && refersToMyEar(aClass.getClassLoader(), myClassLoader, myUrlSet)) {
                    LOG.info("remove ClassInfoCache for: " + aClass);
                    i.remove();
                }
            }
            // ???
            classData.clear();
        } catch (ClassNotFoundException cfne) {
            // nada
        } catch (Exception ex) {
            LOG.error(ex, ex);
        }
    }

    /**
     * Clear references to our class loader from ObjectCopierImpl.
     * @param myUrlSet
     * @param myClassLoader
     */
    private void fixObjectCopierImpl(final Set<Object> myUrlSet, ClassLoader myClassLoader) {
        try {
            Class<?> clazz = null;
            try {
                clazz = Class.forName("com.sun.corba.ee.impl.orbutil.copyobject.ObjectCopierImpl");
            } catch (Exception ex) {
                // gf4
                clazz = Class.forName("org.glassfish.pfl.dynamic.copyobject.impl.ObjectCopierImpl");
            }
            // clean class ObjectCopierImpl
            final Object ccf = getMember(null, clazz, "ccf");
            clearCcf(myUrlSet, myClassLoader, ccf);

        } catch (ClassNotFoundException cnfe) {
            // nada
        } catch (Throwable ex) {
        }
    }

    /**
     * Clear all injectors.
     */
    private void fixInjector() {
        try {
            // clean class com.sun.xml.bind.v2.runtime.reflect.opt.Injector
            final Map<?, ?> injectors = (Map<?, ?>) getMember(null,
                    Class.forName("com.sun.xml.bind.v2.runtime.reflect.opt.Injector"), "injectors");
            injectors.clear();
        } catch (Exception ex) {
            LOG.error(ex, ex);
        }
    }

    /**
     * Fix web bundle class loaders.
     */
    private void fixWebBundleClassloader(final Set<Object> myUrlSet, ClassLoader myClassLoader) {
        try {
            // clean web bundle class loaders
            final Object initctx_factory_builder =
                    getMember(null, Class.forName("javax.naming.spi.NamingManager"), "initctx_factory_builder");
            final Map<?, ?> table = (Map<?, ?>) getMember(initctx_factory_builder, "sc.habitat.byType.store");
            if (table != null) {
                for (final Object oal : table.values()) {
                    final ArrayList<?> al = (ArrayList<?>) oal;
                    for (final Object o : al) {
                        if (!o.getClass().getName().equals("com.sun.hk2.component.LazyInhabitant"))
                            continue;
                        final Object real = getMember(o, "real");
                        if (real == null
                                || !real.getClass().getName().equals("com.sun.hk2.component.SingletonInhabitant"))
                            continue;
                        final Object object = getMember(real, "object");
                        if (object.getClass().getName()
                                .equals("com.sun.enterprise.security.webservices.GFServerPipeCreator")) {
                            final Object webBundleDescriptor =
                                    getMember(object, "endpoint.webComponentImpl.webBundleDescriptor");
                            final ClassLoader cl = (ClassLoader) getMember(webBundleDescriptor, "classLoader");
                            if (refersToMyEar(cl, myClassLoader, myUrlSet)) {
                                LOG.info("releasing LazyInhabitant to my application");
                                setMember(o, "real", null);
                            }
                        } else if (object.getClass().getName().endsWith(".ApplicationRegistry")) {
                            final Map<?, ?> apps = (Map<?, ?>) getMember(object, "apps");
                            for (final Object cai : apps.values()) {
                                ClassLoader cl0 = (ClassLoader) getMember(cai, "appClassLoader");
                                final ArrayList<?> modules = (ArrayList<?>) getMember(cai, "modules");
                                for (final Object moduleInfo : modules) {
                                    ClassLoader cl = (ClassLoader) getMember(moduleInfo, "moduleClassLoader");
                                    if (refersToMyEar(cl, myClassLoader, myUrlSet)) {
                                        final HashSet<?> engines = (HashSet<?>) getMember(moduleInfo, "engines");
                                        for (final Object engineRef : engines) {
                                            try {
                                                final Object cl2 = getMember(engineRef, "appCtr.ejbAppClassLoader");
                                                cl2.toString();
                                            } catch (Exception ex3) {
                                                LOG.error(ex3, ex3);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            // new bug in gf4 / gf4.1
            final Set<?> sortedList =
                    (Set<?>) getMember(initctx_factory_builder, "sc.services.allDescriptors.sortedList");
            if (sortedList != null) {
                Outer: for (Iterator<Object> i = (Iterator<Object>) sortedList.iterator(); i.hasNext();) {
                    final Object v = i.next();
                    final Object o = getMember(v, "cachedValue");
                    if (o != null) {
                        if (o.getClass().getName()
                                .equals("com.sun.enterprise.security.webservices.GFServerPipeCreator")) {

                            final ClassLoader cl = (ClassLoader) getMember(o,
                                    "endpoint.webComponentImpl.webBundleDescriptor.classLoader");
                            if (refersToMyEar(cl, myClassLoader, myUrlSet)) {
                                LOG.info("removing webservice GFServerPipeCreator: " + o);
                                i.remove();
                                continue Outer;
                            }

                            final Set<?> s2 = (Set<?>) getMember(o,
                                    "endpoint.webComponentImpl.webBundleDescriptor.ejbReferences");
                            for (final Object o2 : s2) {
                                final Map<?, ?> m3 = (Map<?, ?>) getMember(o2,
                                        "ejbDescriptor.bundleDescriptor.entityManagerFactories");
                                for (final Object o3 : m3.values()) {
                                    final Map<?, ?> m4 = (Map<?, ?>) getMember(o3, "delegate.session.descriptors");
                                    for (final Object o4 : m4.values()) {
                                        final Object o5 = getMember(o4, "instantiationPolicy.factory");
                                        if (refersToMyEar(o5.getClass().getClassLoader(), myClassLoader, myUrlSet)) {
                                            i.remove();
                                            continue Outer;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception ex) {
            LOG.error(ex, ex);
        }
    }

    /**
     * Release end points.
     * @param myUrlSet
     * @param myClassLoader
     */
    private void fixWebserviceEndpoints(final Set<Object> myUrlSet, ClassLoader myClassLoader) {
        try {
            // fix the WebService endpoints
            final Map<?, ?> modules = (Map<?, ?>) getMember(null,
                    Class.forName("org.glassfish.webservices.JAXWSServletModule"), "modules");

            for (Iterator<?> i = modules.entrySet().iterator(); i.hasNext();) {
                final Entry<?, ?> e = (Entry<?, ?>) i.next();
                final Map<?, ?> endpoints = (Map<?, ?>) getMember(e.getValue(), "endpoints");
                boolean remove = false;
                if (endpoints != null)
                    for (Object endpoint : endpoints.values()) {
                        try {
                            Map<?, ?> beanInfoMap =
                                    (Map<?, ?>) getMember(endpoint, "endpoint.seiModel.jaxbContext.beanInfoMap");

                            // gf4
                            if (beanInfoMap == null)
                                beanInfoMap = (Map<?, ?>) getMember(endpoint,
                                        "serviceDefinition.owner.seiModel.bindingContext.context.beanInfoMap");

                            if (beanInfoMap != null)
                                for (final Object value : beanInfoMap.values()) {
                                    final String vclassName = value.getClass().getName();
                                    if (!vclassName.contains("ClassBeanInfoImpl"))
                                        continue;

                                    final Object[] properties = (Object[]) getMember(value, "properties");
                                    for (final Object prop : properties) {
                                        final String pclassName = prop.getClass().getName();
                                        if (!pclassName.contains("SingleElementLeafProperty"))
                                            continue;

                                        final Object xacc = getMember(prop, "xacc");
                                        final Object acc = getMember(xacc, "acc");

                                        final ClassLoader cl = acc.getClass().getClassLoader();
                                        if (refersToMyEar(cl, myClassLoader, myUrlSet)) {
                                            remove = true;
                                            break;
                                        }
                                        if (remove)
                                            break;
                                    }
                                    if (remove)
                                        break;
                                }
                        } catch (Exception exxx) {
                            LOG.error(exxx, exxx);
                        }
                        if (remove)
                            break;
                    }
                if (remove) {
                    LOG.info("removing webservice endpoints: " + endpoints);
                    i.remove();
                }
            }
        } catch (Exception ex) {
            LOG.error(ex, ex);
        }
    }

    /**
     * fix class copier.
     * @param myUrlSet
     * @param myClassLoader
     */
    private void fixClassCopier(final Set<Object> myUrlSet, ClassLoader myClassLoader) {
        try {
            Class<?> clazz = null;
            try {
                clazz = Class.forName("com.sun.corba.ee.impl.orbutil.copyobject.ClassCopierOrdinaryImpl");
            } catch (Exception ex) {
                // gf4
                clazz = Class.forName("org.glassfish.pfl.dynamic.copyobject.impl.ClassCopierOrdinaryImpl");
            }
            // clean class ClassCopierOrdinaryImpl
            final Map<?, ?> classToClassFieldCopier = (Map<?, ?>) getMember(null, clazz, "classToClassFieldCopier");
            for (Iterator<?> i = classToClassFieldCopier.values().iterator(); i.hasNext();) {
                Object val = i.next();
                Class<?> myClass = (Class<?>) getMember(val, "myClass");
                if (myClass != null && refersToMyEar(myClass.getClassLoader(), myClassLoader, myUrlSet)) {
                    LOG.info("remove classToClassFieldCopier for: " + myClass);
                    i.remove();
                }
            }
        } catch (ClassNotFoundException cfne) {
            // nada
        } catch (Exception ex) {
            LOG.error(ex, ex);
        }
    }

    private void fixORB() {
        try {
            // fix the ORB
            final Object globalPM = getMember(null, Class.forName("com.sun.corba.ee.spi.orb.ORB"), "globalPM");
            final Object weakCache = getMember(globalPM, "classToClassData");
            final Map<?, ?> classToClassData = (Map<?, ?>) getMember(weakCache, "map");

            LOG.info("clearing classToclassData map");
            classToClassData.clear();

        } catch (Exception ex) {
            LOG.error(ex, ex);
        }
    }

    private void fixResourceManager() {
        try {
            final Class<?> resourceManager = Class.forName("com.sun.naming.internal.ResourceManager");
            Map<?, ?> propertiesCache = (Map<?, ?>) getMember(null, resourceManager, "propertiesCache");
            propertiesCache.clear();
        } catch (Exception ex) {
            LOG.error(ex, ex);
        }
    }

    private void fixGlassfishBugxxxx(Set<Object> myUrlSet, ClassLoader myClassLoader) {
        try {
            final Class<?> clazz = Class.forName("org.hibernate.validator.internal.util.ReflectionHelper");
            final Object typeResolver = getMember(null, clazz, "typeResolver");
            final Map<?, ?> map = (Map<?, ?>) getMember(typeResolver, "_resolvedTypes._map");
            if (map != null)
                map.clear();
        } catch (Exception ex) {
            LOG.error(ex, ex);
        }
    }

    /**
     * see http://java.net/jira/browse/GLASSFISH-17468
     * 
     * fixed in 3.1.2
     * 
     * @param myClassLoader
     * @param myUrlSet
     */
    private void fixGlassfishBug17468(Set<Object> myUrlSet, ClassLoader myClassLoader) {
        try {
            // find the context config and flush the error handler.
            final Object digester =
                    getMember(null, Class.forName("org.apache.catalina.startup.ContextConfig"), "contextDigester");

            if (digester != null) {
                LOG.info("nulling errorHandler ");
                setMember(digester, "errorHandler", null);

                final ClassLoader cl = (ClassLoader) getMember(digester, "classLoader");
                if (cl != null) {
                    if (refersToMyEar(cl, myClassLoader, myUrlSet)
                            || refersToMyEar(cl.getParent(), myClassLoader, myUrlSet)) {
                        setMember(digester, "classLoader", null);
                    }
                }
            }

        } catch (Exception ex) {
            LOG.error(ex);
        }
    }

    /**
     * see http://java.net/jira/browse/WSIT-1655
     * 
     * @param myUrlSet
     * @param myClassLoader
     */
    private void fixGlassfishBugWSIT1655(final Set<Object> myUrlSet, ClassLoader myClassLoader) {
        try {
            // clean BaseAuthConfigFactory
            final Map<?, ?> provider2IdsMap = (Map<?, ?>) getMember(null,
                    Class.forName("com.sun.jaspic.config.factory.BaseAuthConfigFactory"), "provider2IdsMap");
            for (final Object acp : provider2IdsMap.keySet()) {
                try {
                    final Map<?, ?> serverConfigMap = (Map<?, ?>) getMember(acp, "serverConfigMap");
                    if (serverConfigMap != null)
                        for (Iterator<?> i = serverConfigMap.entrySet().iterator(); i.hasNext();) {
                            final Entry<?, ?> e = (Entry<?, ?>) i.next();
                            try {
                                final ClassLoader cl = (ClassLoader) getMember(e.getValue(),
                                        "callbackHandler.handler.handlerContext.this$0.seiModel.classLoader");
                                if (cl != null && refersToMyEar(cl, myClassLoader, myUrlSet)) {
                                    i.remove();
                                    continue;
                                }
                            } catch (Exception ex2) {
                                LOG.error(ex2, ex2);
                            }
                            try {
                                final Class<?>[] classes = (Class<?>[]) getMember(e.getValue(),
                                        "callbackHandler.handler.handlerContext.this$0.seiModel.jaxbContext.classes");
                                if (classes != null)
                                    for (Class<?> c : classes) {
                                        if (refersToMyEar(c.getClassLoader(), myClassLoader, myUrlSet)) {
                                            i.remove();
                                            break;
                                        }
                                    }
                            } catch (Exception ex2) {
                                LOG.error(ex2, ex2);
                            }
                        }
                } catch (Exception ex) {
                    LOG.error(ex, ex);
                }
            }
        } catch (Throwable ex) {
            LOG.error(ex, ex);
        }
    }

    /**
     * see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7199818.
     * 
     * @param myUrlSet
     * @param myClassLoader
     */
    private void fixJavaBug7199818(final Set<Object> myUrlSet, ClassLoader myClassLoader) {
        try {
            final Class<?> configuration = Class.forName("javax.security.auth.login.Configuration");
            ClassLoader cl = (ClassLoader) getMember(null, configuration, "contextClassLoader");
            if (refersToMyEar(cl, myClassLoader, myUrlSet)) {
                do {
                    cl = cl.getParent();
                } while (refersToMyEar(cl, myClassLoader, myUrlSet));
                setMember(null, configuration, "contextClassLoader", cl);
            }
        } catch (Exception ex) {
            LOG.error(ex, ex);
        }
    }

    private void clearCcf(final Set<Object> myUrlSet, ClassLoader myClassLoader, final Object ccf)
            throws NoSuchFieldException, IllegalAccessException {
        LOG.info("clear ccf");
        final Map<?, ?> cache = (Map<?, ?>) getMember(ccf, "factoryCache.cache");
        for (Iterator<?> i = cache.values().iterator(); i.hasNext();) {
            final Object cfc = i.next();
            try {
                Class<?> myClass = (Class<?>) getMember(cfc, "classFieldCopier.myClass");
                if (myClass != null && refersToMyEar(myClass.getClassLoader(), myClassLoader, myUrlSet)) {
                    LOG.info("removing ClassCopier for: " + myClass.getName());
                    i.remove();
                    continue;
                }
                myClass = (Class<?>) getMember(cfc, "constructor.clazz");
                if (myClass != null && refersToMyEar(myClass.getClassLoader(), myClassLoader, myUrlSet)) {
                    LOG.info("removing ClassCopier for: " + myClass.getName());
                    i.remove();
                }
            } catch (Exception ex2) {
                LOG.error(ex2, ex2);
            }
        }
    }

    /**
     * Helper function to set a member of the given object.
     * 
     * @param reference
     *            the object to search for member
     * @param memberName
     *            the name of the member
     * @param value
     *            the value to set
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    private void setMember(final Object reference, String memberName, Object value)
            throws NoSuchFieldException, IllegalAccessException {
        setMember(reference, reference.getClass(), memberName, value);
    }

    private void setMember(Object reference, Class<? extends Object> clazz, String memberName, Object value)
            throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
        try {
            final Field field = clazz.getDeclaredField(memberName);
            field.setAccessible(true);
            field.set(reference, value);
        } catch (NoSuchFieldException nsfe) {
            if (clazz.getSuperclass() == null)
                throw nsfe;
            setMember(reference, clazz.getSuperclass(), memberName, value);
        }

    }

    /**
     * Helper functio