3 Replies Latest reply on Jan 3, 2012 7:22 PM by rnott

    Issues with DecoratedCache

    rnott

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

        • 1. Re: Issues with DecoratedCache
          rnott

          One other thing to add:

           

          In blog snippets I've seen, storeAsBinary may need to be set in the configuration but I don't see a way to do that in the AS7 way, given the schema jboss-as-infinispan_1_1.xsd

          • 2. Re: Issues with DecoratedCache
            sannegrinovero

            Hi,

            the DecoratedCache constructor is not needed, in your first line you already received a decorated ac since you used with(ClassLoader)

             

            I think DecoratedCache should no longer be considered public, since this code is valid:

             

            AdvancedCache<Object, Object> cacheONEUsingFooClassLoader = container.getCache( "ONE" ).getAdvancedCache().with( Foo.class.getClassLoader() );


            cacheONEUsingBarClassLoader = ac.with( Bar.class.getClassLoader() );

            1 of 1 people found this helpful
            • 3. Re: Issues with DecoratedCache
              rnott

              That's good to know, I'll refrain from using DecoratedCache then. I had read in a post somewhere (can't find the reference) that when using AdvancedCache with specific classloaders, one also had to use the classloader style when reading and writting:

               

              cache.with( classloader ).put( "foo", foo );

              cache.with( classloader ).get( "foo" );

               

              and that DecoratedCache would eliminate the need for that.

               

              In any case, neither style of using AdvancedCache seems to solve my real question, how does one share a cache between multiple web applications, configured from JBoss AS7? Given writer application A and reader application B, application B will generate a ClassCastException when trying to read values from the cache that were written by application A. It's apparent that the cache is not serializing the entries. Here, I've removed DecoratedCache from the code:

               

              AdvancedCache<?, ?> c = container.getCache( "foo" ).getAdvancedCache().with( Foo.class.getClassLoader() );

              AdvancedCache<String,Foo> cache = (AdvancedCache<String,Foo>) c;

              Foo value = cache.with( Foo.class.getClassLoader() ).get( "foo" );  // cache.get("foo") also fails with CCE

               

              Any ideas how to enable de/serialization on an AS7 configured cache? If it's any help, the actual implementations for cache container and cache are:

               

              Cache container: org.jboss.as.clustering.infinispan.DefaultEmbeddedCacheManager

              Cache: org.jboss.as.clustering.infinispan.DefaultEmbeddedCacheManager$DelegatingCache