I'm trying to use Listeners with filters in a distributed cache with two instances of Infinispan 9.4.0 and Hot Rod Client. When I try to put a new entry in cache, I get the following exception:
[Server:instance-one] 13:09:57,468 ERROR [stderr] (HotRod-ServerHandler-4-2) Exception in thread "HotRod-ServerHandler-4-2" org.infinispan.commons.CacheException: ISPN000936: Class 'com.cm.broadcaster.infinispan.entity.EntityDemo' blocked by deserialization white list. Adjust the configuration serialization white list regular expression to include this class.
This is the cache configuration:
<distributed-cache name="entityCache" remote-timeout="3000" statistics-available="false">
<memory>
<object size="20" strategy="LRU" />
</memory>
<compatibility enabled="true"/>
<file-store path="entity-store" passivation="true"/>
<indexing index="NONE"/>
<state-transfer timeout="60000" chunk-size="1024"/>
</distributed-cache>
This is my demo class:
public class EntityDemo implements Serializable {
private static final long serialVersionUID = 1L;
private long id;
private String name;
private String value;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
The EventFilterFactory:
@NamedFactory(name="entity-event-filter-factory")
public class EntityEventFilterFactory implements CacheEventFilterFactory {
@Override
public CacheEventFilter<String, EntityDemo> getFilter(Object[] params) {
return new EntityEventFilter(params);
}
}
The EventFilter:
public class EntityEventFilter implements Serializable, CacheEventFilter<String, EntityDemo> {
private static final long serialVersionUID = 1L;
private final long filter;
public EntityEventFilter(Object[] params) {
this.filter = Long.valueOf(String.valueOf(params[0]));
}
@Override
public boolean accept(String key, EntityDemo oldValue, Metadata oldMetadata, EntityDemo newValue, Metadata newMetadata, EventType eventType) {
if (eventType.isCreate()) {
if (oldValue.getId() % filter == 0)
return true;
}
return false;
}
}
My test code:
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.addServers("localhost:11222");
RemoteCacheManager rcm = new RemoteCacheManager(cb.build());
RemoteCache<String, EntityDemo> rc = rcm.<String,
EntityDemo>getCache("entityCache");
rc.addClientListener(new CustomListener(), new Object[]{"1"}, null);
EntityDemo e = new EntityDemo();
e.setId(1);
e.setName("Demo");
e.setValue("Demo");
rc.put("1", e);
The listener:
@ClientListener(filterFactoryName="entity-event-filter-factory")
public class CustomListener {
@ClientCacheEntryCreated
public void entryCreated(ClientCacheEntryCreatedEvent<String> event) {
System.out.println("Entry created!");
System.out.println(event.getKey());
}
}
I have looked about white list for serialization, but I have found nothing.
I tried changing object in memory configuration for binary and disabling compatibility, but then I get a new exception:
[Server:instance-one] 13:56:42,131 ERROR [org.infinispan.interceptors.impl.InvocationContextInterceptor] (HotRod-ServerHandler-4-2) ISPN000136: Error executing command PutKeyValueCommand, writing keys [WrappedByteArray{bytes=[B0x01012903033E0131, hashCode=1999574342}]: java.lang.ClassCastException: java.lang.String cannot be cast to com.cm.broadcaster.infinispan.entity.EntityDemo
Can anyone help me with this?
Have you tried this? Passing the -Dinfinispan.deserialization.whitelist.classes property to the server.
http://infinispan.org/docs/stable/upgrading/upgrading.html#deserialization_whitelist