使用某些缓存加载器配置的读取缓存时的ClassCastException

时间:2017-04-28 11:55:10

标签: java caching infinispan

最近我遇到了Infinispan 8.2.1.Final的问题。我在配置缓存加载器的失效模式下有一些直读缓存。该缓存的配置包括两部分。第一部分是XML中的以下模板:

<?xml version="1.0" encoding="UTF-8"?>
<infinispan xmlns="urn:infinispan:config:8.2">
    <cache-container default-cache="default">
        <transport cluster="jcache-cluster"/>
        <invalidation-cache-configuration name="user" mode="SYNC" statistics="true"/>
    </cache-container>
</infinispan>

第二部分是使用JCache API的类和接口的编程配置:

new MutableConfiguration<String, User>()
    .setReadThrough(true).setStoreByValue(true)
    .setCacheLoaderFactory(FactoryBuilder.factoryOf(UserCacheLoader.class));

UserCacheLoader非常简单。它只是在每次调用时创建User的新实例。

在我调用javax.cache.Cache.removeAll()方法之前,一切正常。它会导致以下异常:

Caused by: java.lang.ClassCastException: org.infinispan.test.User cannot be cast to java.lang.String
at org.infinispan.test.UserCacheLoader.load(UserCacheLoader.java:40)
at org.infinispan.jcache.embedded.JCacheLoaderAdapter.loadKey(JCacheLoaderAdapter.java:65)
... 40 more

经过一番调查后,我在课程org.infinispan.jcache.embedded.JCacheLoaderAdapter中找到了以下代码:

@Override
public MarshalledEntry load(Object key) throws PersistenceException {
  V value = loadKey(key);

  if (value != null) {
     Duration expiry = Expiration.getExpiry(expiryPolicy, Expiration.Operation.CREATION);
     long now = ctx.getTimeService().wallClockTime(); // ms
     if (expiry == null || expiry.isEternal()) {
        return ctx.getMarshalledEntryFactory().newMarshalledEntry(value, value, null);
     } else {
        long exp = now + expiry.getTimeUnit().toMillis(expiry.getDurationAmount());
        JCacheInternalMetadata meta = new JCacheInternalMetadata(now, exp);
        return ctx.getMarshalledEntryFactory().newMarshalledEntry(value, value, meta);
     }
  }

  return null;
}

正如您所看到的,使用newMarshalledEntry作为键和值来调用value

是错误还是功能?有没有人面临同样的问题?

P.S。似乎这个问题对于最新版本的Infinispan来说也是实际的。

1 个答案:

答案 0 :(得分:0)

那确实是bug,现在已被@brianheart修复了:)。它将包含在下一版本中。