Nilesh Barai
Nilesh Barai

Reputation: 1322

Hazelcast EntryProcessor ClassNotFoundException

I am using hazelcast cache version 3.11.2 to store and manipulate values in an IMap.

For IMap manipulation I am using EntryProcessor class which extends from AbstractEntryProcessor.

I observe that when put or putIfAbsent method is called on IMap code works fine.

However, while manipulating IMap entries using EntryProcessor I am getting com.hazelcast.nio.serialization.HazelcastSerializationException: java.lang.ClassNotFoundException.

EntryProcessor class

public class CountsEntryProcessor extends AbstractEntryProcessor<String, LocalAndRemoteCount> {

private static final long serialVersionUID = 7155522117375911439L;
long localCount;

public CountsEntryProcessor() {
}

public CountsEntryProcessor(long localCount) {
    this.localCount = localCount;
}

@Override
public Object process(Map.Entry<String, LocalAndRemoteCount> entry) {
    System.out.println("in entry processor");
    if(entry.getValue() != null){
        LocalAndRemoteCount localAndRemoteCount = entry.getValue();
        entry.setValue(new LocalAndRemoteCount(localAndRemoteCount.getLocalCount() + localCount, localAndRemoteCount.getRemoteCount()));
    }
    return null;
}
}

LocalAndRemoteCount class

public class LocalAndRemoteCount implements Serializable{
private static final long serialVersionUID = 1085817105782061822L;
private long localCount;
private long remoteCount;

public LocalAndRemoteCount(long localCount, long remoteCount) {
    this.localCount = localCount;
    this.remoteCount = remoteCount;
}

public long incrementAndGetLocalCount() {
    return ++localCount;
}

public long addAndGetCount(long delta) {
    return localCount=localCount+delta;
}
public long getLocalCount() {
    return localCount;
}

public long getRemoteCount() {
    return remoteCount;
}

public long getTotalCount() {
    return getLocalCount() + getRemoteCount();
}

public void addRemoteLocalCount(long remoteMapLocalCount){
    remoteCount = remoteCount + remoteMapLocalCount;
}

@Override
public String toString(){
    return JsonObjectParser.getJson(LocalAndRemoteCount.class, this);
}

}

Call to entry processor

countsMap is a local Hashmap in my Java code which stores few values.

for (Map.Entry<String, Long> entry : countsMap.entrySet()) {
   publisher.getHazelcast().getCacheClient().getMap("ratelimiter.policies.ingest.map").putIfAbsent(entry.getKey(), new LocalAndRemoteCount(entry.getValue(), 0)); //Works fine
publisher.getHazelcast().getCacheClient().getMap("ratelimiter.policies.ingest.map").executeOnKey(entry.getKey(), new CountsEntryProcessor(entry.getValue())); //throws exception
}

Exception Stacktrace

com.hazelcast.nio.serialization.HazelcastSerializationException: java.lang.ClassNotFoundException: commons.producer.jobs.CountsEntryProcessor
at com.hazelcast.internal.serialization.impl.JavaDefaultSerializers$JavaSerializer.read(JavaDefaultSerializers.java:86)
at com.hazelcast.internal.serialization.impl.JavaDefaultSerializers$JavaSerializer.read(JavaDefaultSerializers.java:75)
at com.hazelcast.internal.serialization.impl.StreamSerializerAdapter.read(StreamSerializerAdapter.java:48)
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toObject(AbstractSerializationService.java:187)
at com.hazelcast.client.impl.protocol.task.map.MapExecuteOnKeyMessageTask.prepareOperation(MapExecuteOnKeyMessageTask.java:42)
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)
at ------ submitted from ------.(Unknown Source)
at com.hazelcast.client.spi.impl.ClientInvocationFuture.resolveAndThrowIfException(ClientInvocationFuture.java:96)
at com.hazelcast.client.spi.impl.ClientInvocationFuture.resolveAndThrowIfException(ClientInvocationFuture.java:33)
at com.hazelcast.spi.impl.AbstractInvocationFuture.get(AbstractInvocationFuture.java:162)
at com.hazelcast.client.spi.ClientProxy.invokeOnPartition(ClientProxy.java:225)
at com.hazelcast.client.spi.ClientProxy.invoke(ClientProxy.java:219)
at com.hazelcast.client.proxy.ClientMapProxy.executeOnKeyInternal(ClientMapProxy.java:1447)
at com.hazelcast.client.proxy.ClientMapProxy.executeOnKey(ClientMapProxy.java:1440)
at commons.producer.jobs.MicroBatchJob.execute(MicroBatchJob.java:61)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
Caused by: java.lang.ClassNotFoundException: commons.producer.jobs.CountsEntryProcessor
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at com.hazelcast.nio.ClassLoaderUtil.tryLoadClass(ClassLoaderUtil.java:288)
at com.hazelcast.nio.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:252)
at com.hazelcast.nio.IOUtil$ClassLoaderAwareObjectInputStream.resolveClass(IOUtil.java:646)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1868)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1751)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2042)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)
at com.hazelcast.internal.serialization.impl.JavaDefaultSerializers$JavaSerializer.read(JavaDefaultSerializers.java:82)
at com.hazelcast.internal.serialization.impl.JavaDefaultSerializers$JavaSerializer.read(JavaDefaultSerializers.java:75)
at com.hazelcast.internal.serialization.impl.StreamSerializerAdapter.read(StreamSerializerAdapter.java:48)
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toObject(AbstractSerializationService.java:187)
at com.hazelcast.client.impl.protocol.task.map.MapExecuteOnKeyMessageTask.prepareOperation(MapExecuteOnKeyMessageTask.java:42)
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)

Is there any config change required in Hazelcast.xml file to use EntryProcessor? Am I missing something here?

Upvotes: 1

Views: 2054

Answers (1)

Nilesh Barai
Nilesh Barai

Reputation: 1322

The only thing I was missing was - had to copy the jar containing entry processor class in user-lib directory.

Upvotes: 1

Related Questions