Issues with DecoratedCache
rnott Jan 3, 2012 4:10 PMI'm attempting to implement a cache that will be shared between multiple web applications running in a JBoss AS 7x server. I've been unable to find a complete example on how to accomplish this but my current direction is an attempt to use DecoratedCache but I'm having issues instantiating this class.
My environment:
java version "1.6.0_29"
Java(TM) SE Runtime Environment (build 1.6.0_29-b11-402-10M3527)
Java HotSpot(TM) 64-Bit Server VM (build 20.4-b02-402, mixed mode)
JBoss AS 7.1.0.CR1b
Infinispan 5.1.0.CR1
I'm externally configuring the cache using the JBoss AS7 service configuration:
{code:xml}
<subsystem xmlns="urn:jboss:domain:infinispan:1.1" default-cache-container="cluster">
<cache-container name="foo-cache" default-cache="foo">
<replicated-cache mode="ASYNC" name="foo" start="EAGER">
<eviction strategy="NONE"/>
</replicated-cache>
</cache-container>
</subsystem>
{code}
My code to load the cache looks like:
{code}
@Resource(mappedName="java:jboss/infinispan/foo-cache")
private CacheContainer container;
protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
AdvancedCache<Object, Object> ac = container.getCache( "foo" ).getAdvancedCache().with( Foo.class.getClassLoader() );
AdvancedCache<?, ?> c = new DecoratedCache<Object, Object>( ac, Foo.class.getClassLoader() );
...
}
{code}
What happens is that I get a ClassCastException when instantiating DecoratedCache:
java.lang.ClassCastException: org.jboss.as.clustering.infinispan.DefaultEmbeddedCacheManager$DelegatingCache cannot be cast to org.infinispan.CacheImpl
org.infinispan.DecoratedCache.<init>(DecoratedCache.java:76)
org.infinispan.DecoratedCache.<init>(DecoratedCache.java:55)
Looking at the source for DecoratedCache, there's this little nugget:
{code}
public DecoratedCache(AdvancedCache<K, V> delegate, ClassLoader classLoader, Flag... flags) {
super(delegate);
if (flags == null || flags.length == 0)
this.flags = null;
else {
this.flags = EnumSet.noneOf(Flag.class);
this.flags.addAll(Arrays.asList(flags));
}
this.classLoader = classLoader;
if (flags == null && classLoader == null)
throw new IllegalArgumentException("There is no point in using a DecoratedCache if neither a ClassLoader nor any Flags are set.");
// Yuk
cacheImplementation = (CacheImpl<K, V>) delegate;
}
{code}
Yuk, indeed. Obviously, what I'm passing in is an implementation of AdvancedCache (as specified) but not an instance of CacheImpl which appears to be privately assumed.
So the question is, How does one implement an Infinispan cache that can be shared by multiple applications (e.g. classloader aware) configured in the JBoss AS7 manner?