Search code examples
ignite

Getting ClassNotFoundException while storing a list of custom objects in ignite cache and works well if I don't use a list


I have a non-persistent ignite cache that stores the following elements,

Key --- java.lang.String Value --- Custom class

public class Transaction {
    private int counter;

    public Transaction(int counter) {
        this.counter = counter;
    }

    public String toString() {
        return String.valueOf(counter);
    }
}

The below code works fine even though I am trying to put a custom object into Ignite.

        IgniteConfiguration cfg = new IgniteConfiguration();
        cfg.setClientMode(true);
        cfg.setPeerClassLoadingEnabled(true);
        cfg.setDeploymentMode(DeploymentMode.CONTINUOUS);

        TcpDiscoveryMulticastIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();
        ipFinder.setAddresses(Collections.singletonList("127.0.0.1:47500..47509"));
        cfg.setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(ipFinder));

        Ignite ignite = Ignition.start(cfg);
        IgniteCache<String, Transaction> cache = ignite.getOrCreateCache("blocked");
        
        cache.put("c1234_t2345_p3456", new Transaction(100);

The below code fails with ClassNotFoundException when I am trying to set a list of objects instead. This code is exactly same as the above, except for the list of objects. Why is it that list of objects fail where-in custom objects stored directly works fine?

        IgniteConfiguration cfg = new IgniteConfiguration();
        cfg.setClientMode(true);
        cfg.setPeerClassLoadingEnabled(true);
        cfg.setDeploymentMode(DeploymentMode.CONTINUOUS);

        TcpDiscoveryMulticastIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();
        ipFinder.setAddresses(Collections.singletonList("127.0.0.1:47500..47509"));
        cfg.setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(ipFinder));

        Ignite ignite = Ignition.start(cfg);
        IgniteCache<String, List<Transaction>> cache = ignite.getOrCreateCache("blocked");

        cache.put("c1234_t2345_p3456", Arrays.asList(new Transaction(100)));

Storing custom objects in-memory to ignite worked, but trying to store List objects instead caused ClassNotFoundException in server. I was able to solve this by copying the custom class definition to "/ignite_home/bin/libs", but curious to know why the first case worked and second case didn't. Can anyone please help me understand what's happening in this case? Is there any other way to resolve this issue?


Solution

  • Ok, after many trials, I have an observation that evens out the differences between the above 2 scenarios. In dynamic declaration of caches as I have done earlier in code, somehow I am seeing the error from Ignite to keep the custom classes in bin/libs folder. But if I define the cache in the ignite-config.xml, then ignite is somehow able to digest both use-case evenly and doesn't even throw the ClassNotFoundException. So, I take the summary here that pre-declared caches are much safer as I am seeing some different behaviour while using them as dynamic ones from code. So, I changed the cache declaration to declarative model and now the above use-cases are working fine.