0

I’m using Hibernate 5.1.0.Final, Spring 3.2.11.RELEASE, and JBoss 7.1.3.Final. I have the following ehcache.xml configuration …

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd" updateCheck="false">

    <!-- This is a default configuration for 256Mb of cached data using the JVM's heap, but it must be adjusted
         according to specific requirement and heap sizes -->
    <defaultCache maxElementsInMemory="10000"
         eternal="false"
         timeToIdleSeconds="86400"
         timeToLiveSeconds="86400"
         overflowToDisk="false"
         memoryStoreEvictionPolicy="LRU">
    </defaultCache> 
    <cache name="main" maxElementsInMemory="10000" />

     <cacheManagerPeerProviderFactory
         class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
         properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1,
         multicastGroupPort=4446, timeToLive=32"/>

    <cacheManagerPeerListenerFactory
        class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
        properties="hostName=localhost, port=40001,
        socketTimeoutMillis=2000"/>    

</ehcache>

This file is included in a number of my web applications (within a JAR, whcih is then packaged into the WAR's WEB-INF/lib directory), all of which are deployed on the same JBoss instance. I would like all the applications to use the same ehcache.xml configuration and thus share data in the same cache. However, many times when I try and deploy all of these applications on this game instance, I get the below error …

2016-04-25 15:21:41,007 ERROR [net.sf.ehcache.distribution.MulticastRMICacheManagerPeerProvider] (ServerService Thread Pool -- 128) Error starting heartbeat. Error was: Can't assign requested address: java.net.SocketException: Can't assign requested address
        at java.net.PlainDatagramSocketImpl.socketSetOption0(Native Method)
        at java.net.PlainDatagramSocketImpl.socketSetOption(PlainDatagramSocketImpl.java:74)
        at java.net.AbstractPlainDatagramSocketImpl.setOption(AbstractPlainDatagramSocketImpl.java:310)
        at java.net.MulticastSocket.setNetworkInterface(MulticastSocket.java:554)
        at java.net.MulticastSocket.joinGroup(MulticastSocket.java:320)
        at net.sf.ehcache.distribution.MulticastKeepaliveHeartbeatReceiver.init(MulticastKeepaliveHeartbeatReceiver.java:88)
        at net.sf.ehcache.distribution.MulticastRMICacheManagerPeerProvider.init(MulticastRMICacheManagerPeerProvider.java:95)
        at net.sf.ehcache.CacheManager.doInit(CacheManager.java:479)
        at net.sf.ehcache.CacheManager.init(CacheManager.java:395)
        at net.sf.ehcache.CacheManager.<init>(CacheManager.java:270)
        at org.hibernate.cache.ehcache.EhCacheRegionFactory.start(EhCacheRegionFactory.java:69)
        at org.hibernate.internal.CacheImpl.<init>(CacheImpl.java:49)
        at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:28)
        at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:20)
        at org.hibernate.service.internal.SessionFactoryServiceRegistryImpl.initiateService(SessionFactoryServiceRegistryImpl.java:46)
        at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:234)
        at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:208)
        at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:189)
        at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:240)
        at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:465)
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:881)
        at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:135)
        at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:50)
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:290)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1573)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1511)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)
        at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1119)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:924)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
        at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:410)
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
        at io.undertow.servlet.core.ApplicationListeners.contextInitialized(ApplicationListeners.java:187)
        at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:195)
        at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:100)
        at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:82)
        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:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
        at org.jboss.threads.JBossThread.run(JBossThread.java:320)

My question is, how can I instruct each web application to use the same second level cache and ehcache configuration?

Dave
  • 15,639
  • 133
  • 442
  • 830
  • Checkout property `hibernate.cache.region_prefix` - this is set by application server to create unique cache region for each deployment, but maybe you can override it in persistence.xml – Radim Vansa Apr 26 '16 at 16:23
  • K, my question is if I set this property to "appA" for appA, "appB" for appB and then appA caches entity X, will app B then be able to find entity X in the second level cache? – Dave Apr 26 '16 at 16:57
  • No, you would have to set it to the same value - the point of this property (and having it set differently) is to isolate the apps. However, I don't know how this will work with classloaders, since class foo.X in appA is probably loaded in different classloader than in appB. – Radim Vansa Apr 27 '16 at 14:29
  • JBoss AS7 and Wildfly come with Infinispan-based 2LC integration out of the box. Although caches are kept per-entity/collection, the underlying infrastructure such as cluster communication...etc are shared for all caches. Would that work better for your use case? :) – Galder Zamarreño May 09 '16 at 14:51

1 Answers1

0

Try packaging the WAR's together into a single composite EAR project. You also will likely want your ehcache.xml file to be outside your packaged EAR (but still on the classpath), so that it can be configured separately by environment (Dev, Test, Prod, etc.)

Dean Clark
  • 3,770
  • 1
  • 11
  • 26
  • So you are sayhing it is impossible to deploy WAR applications in the same JVM (application server) where each one has the same ehcache.xml configuration? – Dave Apr 27 '16 at 13:58
  • If your ehcache.xml is external to your projects (stored somewhere on the file system), I think they could the same configuration. My concern would be the classpath isolation that most containers (e.g. JBoss EAP) use would prevent from sharing actual information. What you'd end up with is all your WARs having their cache configured the same way but not actually sharing the same cache in memory. – Dean Clark Apr 27 '16 at 15:03
  • So you're just guessing, you haven't actually tried this? I ask because I'm reading the JBOss classloading documentation and it talks about unified class loading (it stores only one class per JVM). That suggests it should be able to share things, in the manner I'm describing above. – Dave Apr 28 '16 at 15:54
  • Have I tried to share data across WARs? No. In fact, I've always had the opposite goal in mind, instead using memcached for anything across multiple applications. Yes, the classloader would load each class once in permgen, so I suppose your various applications would have access to their static fields. However, I believe in your case that each WAR would initialize its own singleton for caching, so data would not be shared. I would look towards a product such as gemfire or memcached to meet your needs. – Dean Clark Apr 28 '16 at 16:16