@@ -0,0 +1,3703 @@
+/*%0A * Copyright to the original author or authors.%0A *%0A * Licensed under the Apache License, Version 2.0 (the %22License%22);%0A * you may not use this file except in compliance with the License.%0A * You may obtain a copy of the License at%0A *%0A *      http://www.apache.org/licenses/LICENSE-2.0%0A *%0A * Unless required by applicable law or agreed to in writing, software%0A * distributed under the License is distributed on an %22AS IS%22 BASIS,%0A * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.%0A * See the License for the specific language governing permissions and%0A * limitations under the License.%0A */%0Apackage org.rioproject.cybernode;%0A%0Aimport net.jini.config.ConfigurationException;%0Aimport org.rioproject.config.AggregateConfig;%0Aimport org.rioproject.config.GroovyConfig;%0Aimport org.rioproject.core.ServiceBeanConfig;%0Aimport org.rioproject.core.jsb.ServiceBeanContext;%0Aimport org.rioproject.jsb.JSBContext;%0Aimport org.rioproject.log.LoggerConfig;%0A%0Aimport java.lang.reflect.Field;%0Aimport java.security.AccessController;%0Aimport java.security.PrivilegedAction;%0Aimport java.util.Map;%0A%0A/**%0A * Service termination helper.%0A */%0Apublic class ServiceTerminationHelper %7B%0A%0A    /**%0A     * Cleanup resources that may cause memory leaks%0A     *%0A     * @param context The %3Ccode%3EServiceBeanContext%3C/code%3E to use%0A     */%0A    public static void cleanup(ServiceBeanContext context) %7B%0A        if (context != null) %7B%0A            /* Release any created Handlers */%0A            Map map = context.getServiceBeanConfig().getConfigurationParameters();%0A            LoggerConfig%5B%5D loggerConfigs = (LoggerConfig%5B%5D) map.get(ServiceBeanConfig.LOGGER);%0A            if (loggerConfigs != null) %7B%0A                for (LoggerConfig loggerConfig : loggerConfigs) %7B%0A                    loggerConfig.close();%0A                %7D%0A            %7D%0A%0A            /* If we have a groovy configuration, clean the configuration, clearing%0A             * the class cache and setting the embedded groovy classloader to null */%0A            try %7B%0A                if (context.getConfiguration() instanceof AggregateConfig) %7B%0A                    AggregateConfig ac = (AggregateConfig) context.getConfiguration();%0A                    if (ac.getOuterConfiguration() instanceof GroovyConfig) %7B%0A                        ((GroovyConfig) ac.getOuterConfiguration()).clear();%0A                    %7D%0A                    if (context instanceof JSBContext)%0A                        ((JSBContext) context).setConfiguration(null);%0A                %7D%0A            %7D catch (ConfigurationException e) %7B%0A                /* */%0A            %7D%0A        %7D%0A%0A        /* Services using groovy leak memory on undeployment. The object retaining a reference to the%0A         * GroovyClassLoader (that has as it's parent the ServiceClassLoader) is a static%0A         * org.codehaus.groovy.control.CompilationUnit field in the%0A         * org.codehaus.groovy.transform.ASTTransformationVisitor class */%0A        try %7B%0A            final Class clazz = loadClass(%22org.codehaus.groovy.transform.ASTTransformationVisitor%22);%0A            final Field compUnit = clazz.getDeclaredField(%22compUnit%22);%0A            compUnit.setAccessible(true);%0A            // static field%0A            compUnit.set(null, null);%0A        %7D catch (Throwable t) %7B%0A            // ignore%0A        %7D%0A    %7D%0A%0A    static Class loadClass(final String className) %7B%0A        return AccessController.doPrivileged(new PrivilegedAction%3CClass%3E() %7B%0A            public Class run() %7B%0A                try %7B%0A                    return Thread.currentThread().getContextClassLoader().loadClass(className);%0A                %7D catch (ClassNotFoundException e) %7B%0A                    return null;%0A                %7D%0A            %7D%0A        %7D);%0A    %7D%0A%0A%7D%0A

Clean up service references