killbill-memoizeit

util: work around thread safety bug in Shiro Shiro's EhCacheManager

8/8/2014 3:48:58 PM

Details

diff --git a/util/src/main/java/org/killbill/billing/util/glue/EhCacheManagerProvider.java b/util/src/main/java/org/killbill/billing/util/glue/EhCacheManagerProvider.java
index bd742f8..3577271 100644
--- a/util/src/main/java/org/killbill/billing/util/glue/EhCacheManagerProvider.java
+++ b/util/src/main/java/org/killbill/billing/util/glue/EhCacheManagerProvider.java
@@ -22,6 +22,7 @@ import javax.inject.Provider;
 import org.apache.shiro.cache.ehcache.EhCacheManager;
 import org.apache.shiro.mgt.DefaultSecurityManager;
 import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.session.mgt.eis.CachingSessionDAO;
 
 import net.sf.ehcache.CacheManager;
 
@@ -42,6 +43,11 @@ public class EhCacheManagerProvider implements Provider<EhCacheManager> {
         // Same EhCache manager instance as the rest of the system
         shiroEhCacheManager.setCacheManager(ehCacheCacheManager);
 
+        // It looks like Shiro's cache manager is not thread safe. Concurrent requests on startup
+        // can throw org.apache.shiro.cache.CacheException: net.sf.ehcache.ObjectExistsException: Cache shiro-activeSessionCache already exists
+        // As a workaround, create the cache manually here
+        shiroEhCacheManager.getCache(CachingSessionDAO.ACTIVE_SESSION_CACHE_NAME);
+
         if (securityManager instanceof DefaultSecurityManager) {
             ((DefaultSecurityManager) securityManager).setCacheManager(shiroEhCacheManager);
         }