Search code examples
javaspring-boothazelcast

Hazelcast Spring Boot java.lang.ClassNotFoundException


I am starting hazelcast instance in my spring boot application.

Hazelcast configuration

@Configuration
@EnableCaching
public class HazelcastConfig {
    @Bean
    public Config hazelCastConfig() {
        final Config config = new Config();
        config.setClassLoader(getClass().getClassLoader());
        config.setInstanceName("cache");
        return config;
    }

    @Bean
    public HazelcastInstance hazelcastInstance() {
        return Hazelcast.newHazelcastInstance(hazelCastConfig());
    }
}

And it fails time to time with class not found exception when I call my HTTP endpoint that queries data from hazelcast Map.

java.lang.ClassNotFoundException: com.someOrg.SomeClass
at org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader.loadClass(TomcatEmbeddedWebappClassLoader.java:70) ~[spring-boot-2.0.5.RELEASE.jar!/:2.0.5.RELEASE]
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1137) ~[tomcat-embed-core-8.5.34.jar!/:8.5.34]
at com.hazelcast.nio.ClassLoaderUtil.tryLoadClass(ClassLoaderUtil.java:173) ~[hazelcast-3.9.4.jar!/:3.9.4]
at com.hazelcast.nio.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:147) ~[hazelcast-3.9.4.jar!/:3.9.4]
at com.hazelcast.nio.IOUtil$ClassLoaderAwareObjectInputStream.resolveClass(IOUtil.java:593) ~[hazelcast-3.9.4.jar!/:3.9.4]
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1826) ~[na:1.8.0_131]
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1713) ~[na:1.8.0_131]
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2000) ~[na:1.8.0_131]
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1535) ~[na:1.8.0_131]
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:422) ~[na:1.8.0_131]
at com.hazelcast.internal.serialization.impl.JavaDefaultSerializers$JavaSerializer.read(JavaDefaultSerializers.java:79) ~[hazelcast-3.9.4.jar!/:3.9.4]
at com.hazelcast.internal.serialization.impl.JavaDefaultSerializers$JavaSerializer.read(JavaDefaultSerializers.java:72) ~[hazelcast-3.9.4.jar!/:3.9.4]
at com.hazelcast.internal.serialization.impl.StreamSerializerAdapter.read(StreamSerializerAdapter.java:48) ~[hazelcast-3.9.4.jar!/:3.9.4]
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toObject(AbstractSerializationService.java:191) ~[hazelcast-3.9.4.jar!/:3.9.4]
at com.hazelcast.query.impl.CachedQueryEntry.getValue(CachedQueryEntry.java:75) ~[hazelcast-3.9.4.jar!/:3.9.4]
at com.hazelcast.query.impl.CachedQueryEntry.getTargetObject(CachedQueryEntry.java:108) ~[hazelcast-3.9.4.jar!/:3.9.4]
at com.hazelcast.query.impl.QueryableEntry.extractAttributeValue(QueryableEntry.java:81) ~[hazelcast-3.9.4.jar!/:3.9.4]
at com.hazelcast.query.impl.QueryableEntry.getAttributeValue(QueryableEntry.java:48) ~[hazelcast-3.9.4.jar!/:3.9.4]
at com.hazelcast.query.impl.predicates.AbstractPredicate.readAttributeValue(AbstractPredicate.java:132) ~[hazelcast-3.9.4.jar!/:3.9.4]
at com.hazelcast.query.impl.predicates.AbstractPredicate.apply(AbstractPredicate.java:57) ~[hazelcast-3.9.4.jar!/:3.9.4]
at com.hazelcast.query.PredicateBuilder.apply(PredicateBuilder.java:51) ~[hazelcast-3.9.4.jar!/:3.9.4]
at com.hazelcast.map.impl.query.PartitionScanRunner.run(PartitionScanRunner.java:97) ~[hazelcast-3.9.4.jar!/:3.9.4]
at com.hazelcast.map.impl.query.CallerRunsPartitionScanExecutor.execute(CallerRunsPartitionScanExecutor.java:42) ~[hazelcast-3.9.4.jar!/:3.9.4]
at com.hazelcast.map.impl.query.QueryRunner.runPartitionScanQueryOnGivenOwnedPartition(QueryRunner.java:172) ~[hazelcast-3.9.4.jar!/:3.9.4]
at com.hazelcast.map.impl.query.QueryPartitionOperation.run(QueryPartitionOperation.java:55) ~[hazelcast-3.9.4.jar!/:3.9.4]
at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:194) ~[hazelcast-3.9.4.jar!/:3.9.4]
at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:409) ~[hazelcast-3.9.4.jar!/:3.9.4]
at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.process(OperationThread.java:115) ~[hazelcast-3.9.4.jar!/:3.9.4]
at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.run(OperationThread.java:100) ~[hazelcast-3.9.4.jar!/:3.9.4]

Tried with config.setClassLoader(getClass().getClassLoader()); in hazelcast configuration class and without it - it fails after some time with the same ClassNotFoundException issue.

Why hazelcast fails with this issue and how to fix it ?


Solution

  • I fixed the issue by using Hazelcast feature User Code Deployment

    Configuration file that works for me

    @Configuration
    @EnableCaching
    public class HazelcastConfig {
        @Bean
        public Config hazelCastConfig() {
            final Config config = new Config();            
            config.setClassLoader(Thread.currentThread().getContextClassLoader());
    
            final UserCodeDeploymentConfig distCLConfig = config.getUserCodeDeploymentConfig();
            distCLConfig.setEnabled(true)
              .setClassCacheMode(UserCodeDeploymentConfig.ClassCacheMode.ETERNAL)
              .setProviderMode(UserCodeDeploymentConfig.ProviderMode.LOCAL_CLASSES_ONLY);
    
            return config;
        }
    
        @Bean
        public HazelcastInstance hazelcastInstance() {
            return Hazelcast.newHazelcastInstance(hazelCastConfig());
        }
    }