Infinispan-10.0.1.Final:没有为 Java 类型 java.util.UUID 注册编组器

Infinispan-10.0.1.Final: No marshaller registered for Java type java.util.UUID

从 9.4.16.Final --> 10.0.1.Final 升级 infinispan-jcache 后,由于编组器错误,我无法使用缓存。

https://infinispan.org/blog/

我希望它与 javax.cache.* 一起使用,v9.4.16.Final 就是这种情况。没有使用与 infinispan 相关的 类。

在 v10.0.1.Final 中,我可以在缓存中放入和检索 UUID。但在设置 CacheLoaderFactory 时失败。

进口

import javax.cache.Cache;
import javax.cache.Caching;
import javax.cache.configuration.MutableConfiguration;
import javax.cache.expiry.Duration;
import javax.cache.expiry.ModifiedExpiryPolicy;
import javax.cache.integration.CacheLoader;
import javax.cache.integration.CacheLoaderException;

代码:

final var cachingProvider = Caching.getCachingProvider();
final var cacheManager = cachingProvider.getCacheManager();
final var config = new MutableConfiguration<String,UUID>();
config.setTypes( String.class, UUID.class );
config.setStoreByValue( false );
config.setExpiryPolicyFactory( ModifiedExpiryPolicy.factoryOf( Duration.FIVE_MINUTES ) );
config.setReadThrough( true );
config.setCacheLoaderFactory( () -> new CacheLoader<>() {
    @Override
    public UUID load(String key) throws CacheLoaderException {
        return UUID.randomUUID();
    }

    @Override
    public Map<String,UUID> loadAll(Iterable<? extends String> keys) throws CacheLoaderException {
        return null;
    }
} );

cache = cacheManager.createCache( UUIDCacheTest.class.getName(), config );

cache.get( "Dummy" ); // Throws exception

例外情况是:

Caused by: org.infinispan.persistence.spi.PersistenceException: org.infinispan.commons.marshall.MarshallingException: No marshaller registered for Java type java.util.UUID
    at org.infinispan.marshall.persistence.impl.MarshallableEntryImpl.marshall(MarshallableEntryImpl.java:211)
    at org.infinispan.marshall.persistence.impl.MarshallableEntryImpl.<init>(MarshallableEntryImpl.java:37)
    at org.infinispan.marshall.persistence.impl.MarshalledEntryFactoryImpl.create(MarshalledEntryFactoryImpl.java:64)
    at org.infinispan.jcache.embedded.JCacheLoaderAdapter.loadEntry(JCacheLoaderAdapter.java:51)
    at org.infinispan.persistence.manager.PersistenceManagerImpl.loadFromAllStoresSync(PersistenceManagerImpl.java:830)
    at org.infinispan.persistence.manager.PersistenceManagerImpl.lambda$loadFromAllStores(PersistenceManagerImpl.java:848)
    at org.infinispan.persistence.manager.PersistenceManagerImpl.lambda$supplyOnPersistenceExAndContinue(PersistenceManagerImpl.java:559)
    at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1771)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: org.infinispan.commons.marshall.MarshallingException: No marshaller registered for Java type java.util.UUID
    at org.infinispan.marshall.persistence.impl.PersistenceMarshallerImpl.objectToBuffer(PersistenceMarshallerImpl.java:164)
    at org.infinispan.marshall.persistence.impl.PersistenceMarshallerImpl.objectToBuffer(PersistenceMarshallerImpl.java:132)
    at org.infinispan.mars

Infinispan 10.0.x 对其编组代码进行了重大重构,默认编组器不再基于序列化。请参阅我们的 marshalling user guide 以深入了解可用的各种编组选项。

对于此用例,由于 UUID 是您无法控制的 class,基于序列化的编组可能是最简单的开始方式。有必要显式配置 JavaSerializationMarshaller 并将所需的 classes (UUID) 列入白名单。

要使用 JCache CachingProvider 执行此操作,必须首先为 CacheManager 创建以下 xml 配置文件。

<?xml version="1.0" encoding="UTF-8"?>
<infinispan xmlns="urn:infinispan:config:10.0">
    <cache-container>
        <serialization marshaller="org.infinispan.commons.marshall.JavaSerializationMarshaller">
            <white-list>
              <class>java.util.UUID</class>
            </white-list>
        </serialization>
    </cache-container>
</infinispan>

此 xml 然后用于创建缓存管理器,如下所示:

CachingProvider cachingProvider = Caching.getCachingProvider();
ClassLoader classLoader = SimpleCacheTest.class.getClassLoader();
CacheManager cacheManager = cachingProvider.getCacheManager(classLoader.getResource("example.xml").toURI(), classLoader);

CacheManager 创建的所有后续缓存都将配置为使用 JavaSerializationMarshaller。