ClassCastException with Object stored in Infinispan Cache
kraythen May 13, 2014 10:33 AMGreetings, 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.