Skip to content
Advertisement

Redisson for JCache Session persistence on WebSphere-Liberty: how to pass redisson-jcache.yaml?

Hello Open Liberty experts,

As an R&D effort, I am trying to enable Liberty session persistence backed by Redis via JCache/Redisson. I observe the CLASSPATH seems to be correctly configured via <library> and <httpSessionCache libraryRef> syntax, but the config file is not being passed to org.redisson.jcache.JCacheManager.createCache(). This method is an implementation of javax.cache.CacheManager.createCache()

Here is my server.xml:

<?xml version="1.0" encoding="UTF-8"?>
<server description="defaultServer">
    <!-- Enable features -->
    <featureManager>
        <feature>cdi-2.0</feature>
        <feature>jaxb-2.2</feature>
        <feature>jsf-2.3</feature>
        <feature>jaxrs-2.1</feature>
        <feature>ejbLite-3.2</feature>
        <feature>sessionCache-1.0</feature>        
    </featureManager>

    <!-- Define http & https endpoints -->
    <httpEndpoint id="defaultHttpEndpoint" host="*"
        httpPort="9080" httpsPort="9443" />

    <library id="jCacheVendorLib">
      <fileset dir="${shared.resource.dir}" includes="*"/>
      <folder dir="${shared.resource.dir}" />
    </library>

    <!-- trust JDK’s default truststore -->
    <ssl id="defaultSSLConfig"  trustDefaultCerts="true" />

    <httpSessionCache libraryRef="jCacheVendorLib"
                      uri="file:${shared.resource.dir}/redisson-jcache.yaml" />

    <!-- Automatically expand WAR files and EAR files -->
    <applicationManager autoExpand="true" />

    <!-- Define web application with its context root and location -->
    <webApplication id="javaee-cafe" contextRoot="/"
        location="${server.config.dir}/apps/javaee-cafe.war">
    </webApplication>
</server>

Regardless of what value I set as uri="file:${shared.resource.dir}/redisson-jcache.yaml" I still get this exception at startup time for Liberty.

{
    "host": "javaee-app-simple-cluster-85b47b866c-h5mk4",
    "ibm_datetime": "2021-05-05T02:49:04.369+0000",
    "ibm_messageId": "SESN0307E",
    "ibm_sequence": "1620182944369_0000000000017",
    "ibm_serverName": "defaultServer",
    "ibm_threadId": "0000002a",
    "ibm_userDir": "/opt/ol/wlp/usr/",
    "loglevel": "ERROR",
    "message": "SESN0307E: An exception occurred when initializing the cache. The exception is: java.lang.IllegalStateException: Default configuration hasn't been specified!
  at org.redisson.jcache.JCacheManager.createCache(JCacheManager.java:118)
  at com.ibm.ws.session.store.cache.CacheHashMap.cacheInit(CacheHashMap.java:182)
  at com.ibm.ws.session.store.cache.CacheHashMap.lambda$new$0(CacheHashMap.java:134)
  at com.ibm.ws.session.store.cache.CacheHashMap$$Lambda$90/0000000000000000.run(Unknown Source)
  at java.security.AccessController.doPrivileged(AccessController.java:678)
  at com.ibm.ws.session.store.cache.CacheHashMap.<init>(CacheHashMap.java:133)
  at com.ibm.ws.session.store.cache.CacheStore.<init>(CacheStore.java:33)
  at com.ibm.ws.session.store.cache.CacheStoreService.createStore(CacheStoreService.java:316)
  at com.ibm.ws.session.SessionContext.createStore(SessionContext.java:337)
  at com.ibm.ws.session.SessionContext.createCoreSessionManager(SessionContext.java:254)
  at com.ibm.ws.session.SessionContext.<init>(SessionContext.java:157)
  at com.ibm.ws.webcontainer.session.impl.HttpSessionContextImpl.<init>(HttpSessionContextImpl.java:62)
  at com.ibm.ws.webcontainer31.session.impl.HttpSessionContext31Impl.<init>(HttpSessionContext31Impl.java:37)
  at com.ibm.ws.webcontainer31.session.impl.SessionContextRegistry31Impl.createSessionContextObject(SessionContextRegistry31Impl.java:40)
  at com.ibm.ws.webcontainer.session.impl.SessionContextRegistryImpl.createSessionContext(SessionContextRegistryImpl.java:83)
  at com.ibm.ws.webcontainer.session.impl.SessionContextRegistryImpl.getSessionContext(SessionContextRegistryImpl.java:304)
  at com.ibm.ws.webcontainer.WebContainer.getSessionContext(WebContainer.java:699)
  at com.ibm.ws.webcontainer.VirtualHost.getSessionContext(VirtualHost.java:188)
  at com.ibm.ws.webcontainer.webapp.WebGroup.getSessionContext(WebGroup.java:156)
  at com.ibm.ws.webcontainer.webapp.WebApp.createSessionContext(WebApp.java:1313)
  at com.ibm.ws.webcontainer.webapp.WebApp.commonInitializationStart(WebApp.java:1296)
  at com.ibm.ws.webcontainer.osgi.webapp.WebApp.commonInitializationStart(WebApp.java:254)
  at com.ibm.ws.webcontainer.webapp.WebApp.initialize(WebApp.java:1014)
  at com.ibm.ws.webcontainer.webapp.WebApp.initialize(WebApp.java:6683)
  at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost.startWebApp(DynamicVirtualHost.java:470)
  at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost.startWebApplication(DynamicVirtualHost.java:465)
  at com.ibm.ws.webcontainer.osgi.WebContainer.startWebApplication(WebContainer.java:1178)
  at com.ibm.ws.webcontainer.osgi.WebContainer.access$100(WebContainer.java:109)
  at com.ibm.ws.webcontainer.osgi.WebContainer$3.run(WebContainer.java:975)
  at com.ibm.ws.threading.internal.ExecutorServiceImpl$RunnableWrapper.run(ExecutorServiceImpl.java:239)
  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
  at java.lang.Thread.run(Thread.java:823).",
    "module": "com.ibm.ws.session.store.cache.CacheHashMap",
    "type": "liberty_message"
}

I tried setting a completely bogus value for uri="file:${shared.resource.dir}/redisson-jcache.yaml" and I still get the same result: IllegalStateException as shown above. What am I missing?

Thanks,

Ed

Advertisement

Answer

Sadly solution to this problem is fairly simple, working out the problem was more complicated. There was a typo in the redisson-jcache.yaml file. Since I know Ed we have been talking off stack overflow and we discovered the redisson-jcache.yaml file contained this:

clusterServerConfig:
  password: ${clusterServerConfig.password}
  nodeAddresses:
  - ${clusterServerConfig.nodeAddresses}

it turns out that it should have been:

clusterServersConfig:
  password: ${clusterServerConfig.password}
  nodeAddresses:
  - ${clusterServerConfig.nodeAddresses}

note the correct form has server as plural.

So what went wrong, it turns out that if the reddison yaml file doesn’t parse for any reason it proceeds as if no configuration was provided with no error message to indicate what the problem processing the configuration was. It then throws a cryptic exception saying no configuration was provided.

Inserting a printStackTrace call into the right place in the Redisson code base resulted in a useful error message that said:

Unrecognized field "clusterServerConfig" (class org.redisson.config.Config), not marked as ignorable (23 known properties: "eventLoopGroup", "maxCleanUpDelay", "nettyHook", "keepPubSubOrder", "nettyThreads", "threads", "transportMode", "singleServerConfig", "sentinelServersConfig", "reliableTopicWatchdogTimeout", "useScriptCache", "minCleanUpDelay", "connectionListener", "executor", "codec", "replicatedServersConfig", "clusterServersConfig", "useThreadClassLoader", "masterSlaveServersConfig", "addressResolverGroupFactory", "lockWatchdogTimeout", "cleanUpKeysAmount", "referenceEnabled"])

So the conclusion here is to make absolutely sure your redisson yaml is correct. Having fixed that everything worked.

7 People found this is helpful
Advertisement