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 ?
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());
}
}