0 Replies Latest reply on May 13, 2014 10:33 AM by Robert Simmons

    ClassCastException with Object stored in Infinispan Cache

    Robert Simmons Newbie

      Greetings, I have read the documentation and googled until my fingers bleed but I still cant find out what I am doing wrong here. So if anyone can help, I would appreciate it.

       

      I have a Singleton EJB service that reads objects out of a datastore and stores them in the a cache. However, when I disable and enable the app in EAP 6.2 fetching any object in the cache results in a ClassCastException. Specifically, here is my EAP cache config.

       

      <subsystem xmlns="urn:jboss:domain:infinispan:1.4">

        <cache-container name="mycache" jndi-name="java:jboss/infinispan/mycache">

          <transport lock-timeout="60000"/>

          <replicated-cache name="config_mgr" mode="ASYNC" start="EAGER">

            <expiration lifespan="86400000"/>

          </replicated-cache>

        </cache-container>

      </subsystem>

       

      And then to fetch the cache I do a JNDI lookup on the manager (note that I snipped in only relevant code:

       

      @Singleton

      @Startup

      @Local(ServiceConfigManager.class)

      public class ServiceConfigManagerImpl implements ServiceConfigManager, ServiceConfigManagerAdmin, DynamicMBean {

       

        /** The reference to the cache used to store the {@link ServiceConfig} items in a near cache. */

        private final AdvancedCache<String, ServiceConfig> serviceConfigCache;

       

        /** Default constructor for the implementation of the manager. */

        public ServiceConfigManagerImpl() {

          try {

            final EmbeddedCacheManager cacheMgr = (EmbeddedCacheManager) jndiCtxt.lookup(cacheManagerJNDIName);

            final Cache<String, ServiceConfig> cache = cacheMgr.getCache(this.cacheName);

            this.serviceConfigCache = cache.getAdvancedCache();

          } catch (final Exception ex) {

            if (log.isDebugEnabled()) log.debug("Initialization of ServiceConfigManager failed.");

            throw ServiceConfigExceptionFactory.initializationFailure(ex.getMessage(), ex);

          }

        }

      }

       

      And the object being stored is a basic pojo with an externalizer I have snipped in relevant code:

       

      /** An implementation of a Service configuration with parameters. */

      @Entity

      @Table(name = "SERVICE_CONFIG")

      @SerializeWith(ServiceConfig.ServiceConfigExternalizer.class)

      public class ServiceConfig implements Serializable {

        private static final long serialVersionUID = 1L;

       

        /** Infinispan Externalizer class. */

        public static class ServiceConfigExternalizer implements Externalizer<ServiceConfig> {

          @Override

          public void writeObject(final ObjectOutput output, final ServiceConfig config) throws IOException {

            output.writeInt(config.serviceID);

            output.writeObject(config.configName);

            output.writeLong(config.createdOn.getMillis());

            output.writeLong(config.lastUpdatedOn.getMillis());

            output.writeLong(config.defaultRefreshTime);

            output.writeLong(config.lastRefreshTime.getMillis());

            output.writeObject(config.comments);

            output.writeObject(config.parameters.toArray());

          }

       

       

          @Override

          public ServiceConfig readObject(final ObjectInput input) throws IOException, ClassNotFoundException {

            final ServiceConfig config = new ServiceConfig();

            config.serviceID = input.readInt();

            config.configName = (String) input.readObject();

            config.createdOn = new DateTime(input.readLong());

            config.lastUpdatedOn = new DateTime(input.readLong());

            config.defaultRefreshTime = input.readLong();

            config.lastRefreshTime = new DateTime(input.readLong());

            config.comments = (String) input.readObject();

            config.parameters = new HashSet<Parameter>(Arrays.asList((Parameter[]) input.readObject()));

            return config;

          }

        }

      }

       

      I store the object like so:

       

            this.serviceConfigCache.put(configName, config);

       

      Now before I disable and enable it works fine. But after it gives me multiple instances of the following exception.

       

      [Server:Satellite2Local01] Caused by: java.lang.ClassCastException:serviceconfig.ServiceConfig cannot be cast to serviceconfig.ServiceConfig

      [Server:Satellite2Local01] at serviceconfig.ServiceConfigManagerImpl.refreshOverdueEntities(ServiceConfigManagerImpl.java:102)

      [Server:Satellite2Local01] at sun.reflect.GeneratedMethodAccessor12.invoke(Unknown Source) [:1.7.0_51]


      Clearly this is because the class in the cache is loaded by a different classloader than the one in the re-enabled app. The question is how can I fix this?

       

      Message was edited by: Robert Simmons because of a premature hitting of the submit button.