You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@ignite.apache.org by "Alexei Scherbakov (JIRA)" <ji...@apache.org> on 2017/04/05 14:32:41 UTC

[jira] [Created] (IGNITE-4920) LocalDeploymentSpi resources cleanup on spi.register() might clean resources from other tasks using delegating classloader.

Alexei Scherbakov created IGNITE-4920:
-----------------------------------------

             Summary: LocalDeploymentSpi resources cleanup on spi.register() might clean resources from other tasks using delegating classloader.
                 Key: IGNITE-4920
                 URL: https://issues.apache.org/jira/browse/IGNITE-4920
             Project: Ignite
          Issue Type: Bug
          Components: general
    Affects Versions: 1.6
            Reporter: Alexei Scherbakov
            Assignee: Alexei Scherbakov
             Fix For: 2.1


Culrpit is "if" condition in LocalDelpoymentSpi:

{noformat}
if (entry.getKey().equals(entry.getValue()) && isResourceExist(ldr, entry.getKey()) &&
                        !U.hasParent(clsLdrToIgnore, ldr) && ldrRsrcs.remove(ldr, clsLdrRsrcs)) {
...
}
{noformat}

and can be fixed by adding clsLdrRsrcs.containsKey(entry.getKey()):

{noformat}
if (entry.getKey().equals(entry.getValue()) && isResourceExist(ldr, entry.getKey()) &&
                        !U.hasParent(clsLdrToIgnore, ldr) && clsLdrRsrcs.containsKey(entry.getKey()) && ldrRsrcs.remove(ldr, clsLdrRsrcs)) {
...
}
{noformat}

Reproducer (might require multiple runs)

{noformat}
/** */
public class Main {
    public static void main(String args[]) throws MalformedURLException, ClassNotFoundException {
        System.setProperty("IGNITE_CACHE_REMOVED_ENTRIES_TTL", "1");

        IgniteConfiguration cfg = new IgniteConfiguration();
        cfg.setPeerClassLoadingEnabled(true);

        TcpDiscoverySpi spi = new TcpDiscoverySpi();
        spi.setIpFinder(new TcpDiscoveryVmIpFinder(true));

        cfg.setDiscoverySpi(spi);

        final Ignite ignite = Ignition.start(cfg);

        final ClassLoader moduleClsLdr = Main.class.getClassLoader();

        final ClassLoader moduleCLImpl = new DelegateClassLoader(null, moduleClsLdr);

        for (int i = 0; i < 1000000; i++)
            try {
                Class clazz = moduleCLImpl.loadClass("Main$CallFunction");

                ignite.compute().call(
                    (IgniteCallable)clazz.getDeclaredConstructor(ClassLoader.class).newInstance(moduleCLImpl)
                );
            }
            catch (Exception e) {
                e.printStackTrace();
            }

        System.out.println("Done");
    }

    public static class CallFunction implements IgniteCallable, GridPeerDeployAware {
        transient ClassLoader classLoader;

        public CallFunction(ClassLoader cls) {
            this.classLoader = cls;
        }

        public Object call() throws Exception {
            return null;
        }

        public Class<?> deployClass() {
            return this.getClass();
        }

        public ClassLoader classLoader() {
            return classLoader;
        }
    }

    public static class DelegateClassLoader extends ClassLoader {
        private ClassLoader delegateCL;

        public DelegateClassLoader(ClassLoader parent, ClassLoader delegateCL) {
            super(parent); // Parent doesn't matter.
            this.delegateCL = delegateCL;
        }

        @Override
        public URL getResource(String name) {
            return delegateCL.getResource(name);
        }

        @Override
        public Class<?> loadClass(String name) throws ClassNotFoundException {
            return delegateCL.loadClass(name);
        }
    }
}
{noformat}



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)