Our Problem might be similar to that one: Hazelcast ClassNotFoundException for replicated maps Since the description of the environment is not given in detail I describe our problematic enironment here: We have a dedicated Hazelcast Server(Member), out of the box with some config. No additional classes added (The ones from our project). Then we got two Hazelcast Clients using this Member with several of our own classes. The Clients intend to use Replicated Maps, so at some point in our software they do "hazelcastInstance.getReplicatedMap("MyName")" and then do some put operations. Doing this, the dedicated hazelcast server throws a ClassNotFound for our classes we want to put into the replicated map. I understand this. How should he know about the classes. Then I change to a Map insteadof replicatedMap. "hazelcastInstance.getMap("MyName")" With no other change it works. And this is what makes me wonder how that can be? Does this have to do with different InMemory Storage? Does replicatedMap here behave differently ? Hazelcast Version is: 3.9.2 One info might be important: the Client configures a NearCache for all the maps used:
EvictionConfig evictionConfig = new EvictionConfig()
.setMaximumSizePolicy(EvictionConfig.MaxSizePolicy.ENTRY_COUNT)
.setSize(eapCacheId.getMaxAmountOfValues());
new NearCacheConfig()
.setName(eapCacheId.buildFullName())
.setInMemoryFormat(InMemoryFormat.OBJECT)
.setInvalidateOnChange(true)
.setEvictionConfig(evictionConfig);
}
I changed the InMemoryFormat to BINARY. Still the same ClassNotFound
The Start of the stacktrace is:
at com.hazelcast.internal.serialization.impl.JavaDefaultSerializers$JavaSerializer.read(JavaDefaultSerializers.java:224)
at com.hazelcast.internal.serialization.impl.StreamSerializerAdapter.read(StreamSerializerAdapter.java:48)
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toObject(AbstractSerializationService.java:185)
at com.hazelcast.spi.impl.NodeEngineImpl.toObject(NodeEngineImpl.java:339)
EDIT: wrote a little Test do demonstrate my problem:
package de.empic.hazelclient.client;
import com.hazelcast.client.HazelcastClient;
import com.hazelcast.client.config.ClientConfig;
import com.hazelcast.config.EvictionConfig;
import com.hazelcast.config.InMemoryFormat;
import com.hazelcast.config.NearCacheConfig;
import com.hazelcast.core.HazelcastInstance;
import java.util.Map;
import java.util.Random;
public class HazelClient {
private static final String[] MAP_KEYS = {"Mike", "Ben", "Luis", "Adria", "Lena"};
private static final String MAP_NAME = "Regular Map" ;
private static final String REPLICATED_MAP_NAME = "Replicated Map" ;
private static final String CACHE_MEMBERS = "192.168.56.101:5701" ;
private static final String MNGT_CENTER = "192.168.56.101:5701" ;
HazelcastInstance hazelClientInstance = null ;
private static Random rand = new Random(System.currentTimeMillis());
public static void main(String[] args) {
new HazelClient(true).loop();
}
private HazelClient(boolean useNearCache)
{
ClientConfig cfg = prepareClientConfig(useNearCache) ;
hazelClientInstance = HazelcastClient.newHazelcastClient(cfg);
}
private void loop()
{
Map<String, SampleSerializable> testMap = hazelClientInstance.getMap(MAP_NAME);
Map<String, SampleSerializable> testReplicatedMap = hazelClientInstance.getReplicatedMap(REPLICATED_MAP_NAME);
int count = 0 ;
while ( true )
{
// do a random write to map
testMap.put(MAP_KEYS[rand.nextInt(MAP_KEYS.length)], new SampleSerializable());
// do a random write to replicated map
testReplicatedMap.put(MAP_KEYS[rand.nextInt(MAP_KEYS.length)], new SampleSerializable());
if ( ++count == 10)
{
// after a while we print the map contents
System.out.println("MAP Content -------------------------");
printMapContent(testMap) ;
System.out.println("REPLIACTED MAP Content --------------");
printMapContent(testReplicatedMap) ;
count = 0 ;
}
// we do not want to drown in system outs....
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void printMapContent(Map<String, SampleSerializable> map)
{
for ( String currKey : map.keySet())
{
System.out.println(String.format(" - %s -> %s", currKey, map.get(currKey)));
}
}
private ClientConfig prepareClientConfig(boolean useNearCache)
{
ClientConfig cfg = new ClientConfig();
cfg.setInstanceName("SampleInstance");
cfg.getProperties().put("hazelcast.client.statistics.enabled", "true");
cfg.getProperties().put("hazelcast.client.statistics.period.seconds", "5");
if ( useNearCache )
{
cfg.addNearCacheConfig(defineNearCache(MAP_NAME));
cfg.addNearCacheConfig(defineNearCache(REPLICATED_MAP_NAME));
}
// we use a single member for demo
String[] members = {CACHE_MEMBERS} ;
cfg.getNetworkConfig().addAddress(members);
return cfg ;
}
private NearCacheConfig defineNearCache(String name)
{
EvictionConfig evictionConfig = new EvictionConfig()
.setMaximumSizePolicy(EvictionConfig.MaxSizePolicy.ENTRY_COUNT)
.setSize(Integer.MAX_VALUE);
NearCacheConfig nearCacheConfig = new NearCacheConfig()
.setName(name)
.setInMemoryFormat(InMemoryFormat.OBJECT)
.setInvalidateOnChange(true)
.setEvictionConfig(evictionConfig) ;
return nearCacheConfig;
}
}
To have the full info, the Hazelcast member is started with the following xml:
<?xml version="1.0" encoding="UTF-8"?>
<hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config https://hazelcast.com/schema/config/hazelcast-config-3.8.xsd"
xmlns="http://www.hazelcast.com/schema/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<instance-name>server-cache</instance-name>
<network>
<port>5701</port>
<join>
<multicast enabled="false"/>
<tcp-ip enabled="true">
<members>192.168.56.101:5701</members>
</tcp-ip>
</join>
<public-address>192.168.56.101:5701</public-address>
</network>
<management-center enabled="true">http://192.168.56.101:6679/mancenter</management-center>
</hazelcast>
The fact that the Hazelcast Member is running in docker while the clients are not is not important I think.