I am using multi node hazelcast (3.11 version) cluster. My use case is, during hazelcast startup, I want each member to load the data in the Imap. When java client connects to hazelcast cluster, it should be able to fetch data from the imap using the maploader configured at cluster level.
I have configured map store configuration in hazelcast.xml for each node.
I have added mapstore configuration in hazelcast.xml. This file is placed inside bin folder of each hazelcast node.
hazelcast.xml configuration for each node:
<?xml version="1.0" encoding="UTF-8"?>
<hazelcast
<properties>
<property name="hazelcast.initial.min.cluster.size">2</property>
</properties>
<management-center enabled="true">
</management-center>
<network>
<port auto-increment="true">5701</port>
<join>
<multicast enabled="false">
<multicast-group>224.2.2.3</multicast-group>
<multicast-port>2434</multicast-port>
<multicast-timeout-seconds>1</multicast-timeout-seconds>
</multicast>
<tcp-ip enabled="true" connection-timeout-seconds="3">
</tcp-ip>
</join>
<interfaces enabled="true">
<interface>127.0.0.1</interface>
</interfaces>
</network>
<map name="testmap">
<backup-count>1</backup-count>
<time-to-live-seconds>0</time-to-live-seconds>
<max-idle-seconds>0</max-idle-seconds>
<map-store enabled="true">
<class-name>com.bm.mapstore.OnboardingMapLoader</class-name>
<write-delay-seconds>0</write-delay-seconds>
</map-store>
</map>
</hazelcast>
Code for class OnboardingMapLoader is part of a jar file, I have added that jar file in user-lib folder of hazelcast node, so that class is available to each node to load the data. This jar file is available to each node in the cluster.
Now when hazelcast java client, connects to hazelcast cluster and try to fetch the data from distributed IMap, I get below exception:
Caused by: java.lang.ClassNotFoundException: com.bm.mapstore.OnboardingMapLoader
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at com.hazelcast.nio.ClassLoaderUtil.tryLoadClass(ClassLoaderUtil.java:288)
at com.hazelcast.nio.ClassLoaderUtil.newInstance0(ClassLoaderUtil.java:212)
at com.hazelcast.nio.ClassLoaderUtil.newInstance(ClassLoaderUtil.java:193)
at com.hazelcast.map.impl.mapstore.StoreConstructor.getStoreFromClassOrNull(StoreConstructor.java:81)
at com.hazelcast.map.impl.mapstore.StoreConstructor.createStore(StoreConstructor.java:46)
at com.hazelcast.map.impl.mapstore.BasicMapStoreContext.create(BasicMapStoreContext.java:124)
at com.hazelcast.map.impl.mapstore.MapStoreContextFactory.createMapStoreContext(MapStoreContextFactory.java:48)
at com.hazelcast.map.impl.MapContainer.<init>(MapContainer.java:155)
at com.hazelcast.map.impl.MapServiceContextImpl$1.createNew(MapServiceContextImpl.java:194)
at com.hazelcast.map.impl.MapServiceContextImpl$1.createNew(MapServiceContextImpl.java:190)
at com.hazelcast.util.ConcurrencyUtil.getOrPutSynchronized(ConcurrencyUtil.java:93)
at com.hazelcast.map.impl.MapServiceContextImpl.getMapContainer(MapServiceContextImpl.java:278)
at com.hazelcast.map.impl.operation.MapOperationProviders.getOperationProvider(MapOperationProviders.java:47)
at com.hazelcast.map.impl.MapServiceContextImpl.getMapOperationProvider(MapServiceContextImpl.java:747)
at com.hazelcast.client.impl.protocol.task.map.AbstractMapPartitionMessageTask.getMapOperationProvider(AbstractMapPartitionMessageTask.java:36)
at com.hazelcast.client.impl.protocol.task.map.MapGetMessageTask.prepareOperation(MapGetMessageTask.java:54)
at com.hazelcast.client.impl.protocol.task.AbstractPartitionMessageTask.processMessage(AbstractPartitionMessageTask.java:62)
at com.hazelcast.client.impl.protocol.task.AbstractMessageTask.initializeAndProcessMessage(AbstractMessageTask.java:123)
at com.hazelcast.client.impl.protocol.task.AbstractMessageTask.doRun(AbstractMessageTask.java:111)
at com.hazelcast.client.impl.protocol.task.AbstractMessageTask.run(AbstractMessageTask.java:101)
at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:161)
at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.process(OperationThread.java:159)
at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.process(OperationThread.java:127)
at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.run(OperationThread.java:110)
Apr 19, 2019 1:51:08 PM com.hazelcast.client.connection.ClientConnectionManager
Hazelcast java client code:
import java.util.Map;
import com.hazelcast.client.HazelcastClient;
import com.hazelcast.client.config.ClientConfig;
import com.hazelcast.core.HazelcastInstance;
public class AppTest {
public static void main(String[] args) {
ClientConfig config = new ClientConfig();
String[] addresses = { "localhost:5701", "localhost:5702" };
config.getNetworkConfig().addAddress(addresses);
HazelcastInstance hazelcastInstance = HazelcastClient.newHazelcastClient(config);
Map<Integer, String> imap = hazelcastInstance
.getMap("testmap");
System.out.println(imap.get("6001"));
hazelcastInstance.shutdown();
}
}
Maploader source code
package com.bm.mapstore;
import java.io.Serializable;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.bson.Document;
import org.bson.codecs.configuration.CodecProvider;
import org.bson.codecs.configuration.CodecRegistries;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.codecs.pojo.Convention;
import org.bson.codecs.pojo.Conventions;
import org.bson.codecs.pojo.PojoCodecProvider;
import com.bm.entity.Onboarding;
import com.hazelcast.core.MapLoader;
import com.mongodb.BasicDBObject;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
public class OnboardingMapLoader implements MapLoader<String, Onboarding>, Serializable {
private static final long serialVersionUID = 1L;
private MongoClient mongoClient;
private MongoDatabase db;
private MongoCollection collection;
private String uri = "mongodb://localhost:27017/demodb";
public MongoClient getMongoClient() {
return this.mongoClient;
}
public void setMongoClient(MongoClient mongoClient) {
this.mongoClient = mongoClient;
}
public MongoDatabase getDb() {
return this.db;
}
public void setDb(MongoDatabase db) {
this.db = db;
}
public OnboardingMapLoader() {
CodecRegistry pojoCodecRegistry = CodecRegistries
.fromRegistries(new CodecRegistry[] { MongoClient.getDefaultCodecRegistry(),
CodecRegistries.fromProviders(new CodecProvider[] { PojoCodecProvider.builder()
.conventions(Arrays.asList(new Convention[] { Conventions.ANNOTATION_CONVENTION }))
.automatic(true).build() }) });
this.mongoClient = new MongoClient(new MongoClientURI(uri));
this.db = this.mongoClient.getDatabase("dbvadd1").withCodecRegistry(pojoCodecRegistry);
this.collection = this.db.getCollection("onboarding");
}
@Override
public Onboarding load(String key) {
System.out.println("---------------inside load key is -----------------" + key);
BasicDBObject searchQuery = new BasicDBObject();
searchQuery.put("_id", key);
Document doc = (Document) collection.find(searchQuery).first();
Onboarding onboarding = new Onboarding();
onboarding.setSvcInvkrId(doc.getString("_id"));
onboarding.setAllowMultiple(doc.getString("allowMultiple"));
onboarding.setBid(new BigInteger(doc.getString("bid")));
System.out.println("---------------inside load onboarding is -----------------" + onboarding);
return onboarding;
}
@Override
public Map<String, Onboarding> loadAll(Collection<String> keys) {
Map<String, Onboarding> result = new HashMap();
FindIterable<Document> documents = this.collection.find();
for (MongoCursor localMongoCursor = documents.iterator(); localMongoCursor.hasNext();) {
Document doc = (Document) localMongoCursor.next();
Onboarding onboarding = new Onboarding();
onboarding.setSvcInvkrId(doc.getString("_id"));
onboarding.setAllowMultiple(doc.getString("allowMultiple"));
onboarding.setBid(new BigInteger(doc.getString("bid")));
result.put(onboarding.getSvcInvkrId(), onboarding);
}
System.out.println("---------------inside loadAll result is-----------------" + result);
return result;
}
public Set<String> loadAllKeys() {
return new HashSet<String>(Arrays.asList("6001", "6002"));
}
}
Please help to solve the class not found exception coming at client code due to the MapLoader. Let me know if I am missing any configuration at client side or server side.