I’m trying to deploy a new application in which we use Ignite as
compute grid and send them broadcast messages from different client
nodes. The problem is that we are storing a helper class in the
workers/servers localMap while using SHARED deployment mode with the
peer class loader. According to the documentation: “classes from
different master nodes with the same user version will share the same
class loader on worker nodes” but in reality every master node has a
different classloader in the worker node. I have a small minimal
example that reproduces the issue.

public class Client {

        public static void main(String []args) throws InterruptedException {
                IgniteConfiguration config = new IgniteConfiguration();
                IgniteDiscoverySpi discoverySpi = new TcpDiscoverySpi()
                                .setIpFinder(new
TcpDiscoveryVmIpFinder().setAddresses(List.of(“localhost:47500..47509”)))
                                .setJoinTimeout(600_000);

                config.setPeerClassLoadingEnabled(true);
                config.setDiscoverySpi(discoverySpi);
                config.setDeploymentMode(DeploymentMode.SHARED);
                config.setClientMode(true);

                Ignite ignite = Ignition.start(config);

                for (int i = 0; i < 10; i++) {
                        ignite.compute().broadcast(new LocalMapUser());
                        Thread.sleep(5_000);
                }

                Ignition.stopAll(true);
        }

        public static class LocalMapUser implements IgniteRunnable {
                @IgniteInstanceResource
                public transient Ignite ignite;

                @Override
                public void run() {
                        System.out.println(“ - Before - “);
                        A a;
                        try {
                                a = (A)
ignite.cluster().nodeLocalMap().computeIfAbsent(“a”, k -> new A());
                        } catch (ClassCastException e) {

System.err.println(“ClassCastException: “ + e.getMessage());
                                a = new A();
                                ignite.cluster().nodeLocalMap().put(“a”, a);
                        }
                        a.doSomething();
                        System.out.println(“ - After - “);
                }
        }

        public static class A {
                private int cache = 0;

                void doSomething() {
                        cache++;
                        System.out.println(“Hello World: “ + cache);
                }
        }
}

public class Server {

        public static void main(String []args) {
                IgniteConfiguration config = new IgniteConfiguration();
                IgniteDiscoverySpi discoverySpi = new TcpDiscoverySpi()
                                .setIpFinder(new
TcpDiscoveryVmIpFinder().setAddresses(List.of(“localhost:47500..47509”)))
                                .setJoinTimeout(600_000);

                config.setPeerClassLoadingEnabled(true);
                config.setDiscoverySpi(discoverySpi);
                config.setDeploymentMode(DeploymentMode.SHARED);
                config.setClientMode(false);

                Ignition.start(config);
        }

}

Of course this two classes must be executed from different classpaths
to reproduce the issue. In this example if just one client/master node
runs everything works as expected, but as soon as I have two
client/master nodes running at the same time (with the broadcast
interleaved) the will both start trashing hitting the
ClassCastException in every execution, showing the message:

ClassCastException: class Client$A cannot be cast to class Client$A
(Client$A is in unnamed module of loader
org.apache.ignite.internal.managers.deployment.GridDeploymentClassLoader
@71732d48; Client$A is in unnamed module of loader
org.apache.ignite.internal.managers.deployment.GridDeploymentClassLoader
@2f6ed6ac)

For some reason they have different classloaders. Am I missing something?

Ignite version: 2.7.6
Java version: OpenJDK 11.0.9

Reply via email to