I am getting class not found exception for SQL query and Predicate search and can't figure out why.
Exception:
Method threw 'com.hazelcast.nio.serialization.HazelcastSerializationException' exception. java.lang.ClassNotFoundException: com.mypackage.TestValue
Oct 01, 2021 10:57:14 AM com.hazelcast.map.impl.query.QueryPartitionOperation
SEVERE: [192.168.99.1]:5701 [nifi] [4.2.1] java.lang.ClassNotFoundException: com.mypackage.TestValue
com.hazelcast.nio.serialization.HazelcastSerializationException: java.lang.ClassNotFoundException: com.mypackage.TestValue
at com.hazelcast.internal.serialization.impl.defaultserializers.JavaDefaultSerializers$JavaSerializer.read(JavaDefaultSerializers.java:90)
at com.hazelcast.internal.serialization.impl.defaultserializers.JavaDefaultSerializers$JavaSerializer.read(JavaDefaultSerializers.java:79)
at com.hazelcast.internal.serialization.impl.StreamSerializerAdapter.read(StreamSerializerAdapter.java:44)
at com.hazelcast.internal.serialization.impl.AbstractSerializationService.toObject(AbstractSerializationService.java:208)
at com.hazelcast.query.impl.CachedQueryEntry.getValue(CachedQueryEntry.java:98)
at com.hazelcast.query.impl.CachedQueryEntry.getTargetObject(CachedQueryEntry.java:185)
at com.hazelcast.query.impl.QueryableEntry.extractAttributeValue(QueryableEntry.java:108)
at com.hazelcast.query.impl.QueryableEntry.getAttributeValue(QueryableEntry.java:62)
at com.hazelcast.query.impl.predicates.AbstractPredicate.readAttributeValue(AbstractPredicate.java:145)
at com.hazelcast.query.impl.predicates.AbstractPredicate.apply(AbstractPredicate.java:62)
at com.hazelcast.query.impl.predicates.AndPredicate.apply(AndPredicate.java:136)
at com.hazelcast.map.impl.query.PartitionScanRunner$1.accept(PartitionScanRunner.java:104)
at com.hazelcast.map.impl.query.PartitionScanRunner$1.accept(PartitionScanRunner.java:89)
at com.hazelcast.map.impl.recordstore.DefaultRecordStore.forEach(DefaultRecordStore.java:278)
at com.hazelcast.map.impl.recordstore.DefaultRecordStore.forEach(DefaultRecordStore.java:261)
at com.hazelcast.map.impl.recordstore.DefaultRecordStore.forEachAfterLoad(DefaultRecordStore.java:291)
at com.hazelcast.map.impl.query.PartitionScanRunner.run(PartitionScanRunner.java:89)
at com.hazelcast.map.impl.query.CallerRunsPartitionScanExecutor.execute(CallerRunsPartitionScanExecutor.java:43)
at com.hazelcast.map.impl.query.QueryRunner.runPartitionIndexOrPartitionScanQueryOnGivenOwnedPartition(QueryRunner.java:236)
at com.hazelcast.map.impl.query.QueryPartitionOperation.runInternal(QueryPartitionOperation.java:46)
at com.hazelcast.map.impl.operation.MapOperation.run(MapOperation.java:115)
at com.hazelcast.spi.impl.operationservice.Operation.call(Operation.java:189)
at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.call(OperationRunnerImpl.java:272)
at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:248)
at com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:213)
at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.process(OperationThread.java:175)
at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.process(OperationThread.java:139)
at com.hazelcast.spi.impl.operationexecutor.impl.OperationThread.executeRun(OperationThread.java:123)
at com.hazelcast.internal.util.executor.HazelcastManagedThread.run(HazelcastManagedThread.java:102)
Caused by: java.lang.ClassNotFoundException: com.mypackage.TestValue
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
at com.hazelcast.internal.nio.ClassLoaderUtil.tryLoadClass(ClassLoaderUtil.java:289)
at com.hazelcast.internal.nio.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:249)
at com.hazelcast.internal.nio.IOUtil$ClassLoaderAwareObjectInputStream.resolveClass(IOUtil.java:910)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1984)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1848)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2158)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1665)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:501)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:459)
at com.hazelcast.internal.serialization.impl.defaultserializers.JavaDefaultSerializers$JavaSerializer.read(JavaDefaultSerializers.java:86)
... 28 more
com.mypackage.HazelcastService:
Collection<HazelcastInstance> instances = HazelcastClient.getAllHazelcastClients();
Optional<HazelcastInstance> instance = instances.stream().findAny();
if (!instance.isPresent()) return;
IMap<String, TestValue> cacheMap = instance.get().getMap("test");
cacheMap.put("1", new TestValue(1, 1L));
cacheMap.put("2", new TestValue(2, 2L));
cacheMap.put("5", new TestValue(5, 5L));
cacheMap.put("9", new TestValue(9, 9L));
TestValue tv = cacheMap.get("1"); // works
Collection<TestValue> values = cacheMap.values(); // works
Predicate<String, TestValue> gt = Predicates.greaterThan("testInt", 3);
Predicate<String, TestValue> lt = Predicates.lessThan("testInt", 7);
Predicate<String, TestValue> predicate = Predicates.and(gt, lt);
Collection<TestValue> testValues = cacheMap.values(predicate); // fails
SqlRow row = instance.get().getSql().execute("SELECT this FROM test WHERE testInt = 1").iterator().next(); // fails with whatever query I try
com.mypackage.TestValue class is simple pojo
public class TestValue implements Serializable {
private static final long serialVersionUID = 333333L;
private Integer testInt;
private Long testLong;
public TestValue(Integer testInt, Long testLong) {
this.testInt = testInt;
this.testLong = testLong;
}
public TestValue() {
}
public Integer getTestInt() {
return testInt;
}
public Long getTestLong() {
return testLong;
}
public void setTestInt(Integer testInt) {
this.testInt = testInt;
}
public void setTestLong(Long testLong) {
this.testLong = testLong;
}
}
This is just local env, everything running on my machine, single Hazelcast instance. My code matches examples in official documentation.
Hazelcast version: 4.2.1
Java version: 1.8
CodePudding user response:
You code reads as:
Collection<HazelcastInstance> instances = HazelcastClient.getAllHazelcastClients();
Optional<HazelcastInstance> instance = instances.stream().findAny();
It means that the Hazelcast instance is a client. Hence, you must have a Hazelcast node running as a separate process.
The problem is that your class is known on the client side, not on the server side. Since your query runs server-side, you need to put your class on the server classpath, for example, when you start it, or serialize your class in JSON so it can be queried in an agnostic way.