javacachinginfinispanjcache

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


After upgrading infinispan-jcache from 9.4.16.Final --> 10.0.1.Final, I am unable to use the cache due to marshaller error.

See https://infinispan.org/blog/

I want it working with javax.cache.*,which was the case with v9.4.16.Final. No infinispan related classes are used.

In v10.0.1.Final, I can put and retrieve UUID from the cache. But fails when CacheLoaderFactory is set.

Imports

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;

Code:

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

The exception is:

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$19(PersistenceManagerImpl.java:848)
    at org.infinispan.persistence.manager.PersistenceManagerImpl.lambda$supplyOnPersistenceExAndContinue$9(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

Solution

  • Infinispan 10.0.x introduced a significant refactoring of it's marshalling code, with the default marshaller no longer being based on Serialization. Please see our marshalling user guide for an in-depth explanation of the various marshalling options that are available.

    For this use-case, as UUID is a class out of your control, Serialization based marshalling is probably the easiest way to begin. It's necesary to explicitly configure the JavaSerializationMarshaller and white list the required classes (UUID).

    To do this with a JCache CachingProvider, it's necessary to first create the following xml configuration file for the CacheManager.

    <?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>
    

    This xml is then used to create the CacheManager as follows:

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

    All subsequent caches created by the CacheManager will be configured to utilise the JavaSerializationMarshaller.