Pivotal Knowledge Base

Follow

ClassCastException when Hot Deploy Application JARs

Applies To

Gemfire 7.x and later

Purpose

This document contains a solution for the hot deployment of application JARs with a PDX serialized domain class to avoid a possible ClassCastException exception.

Symptom

When hot deploying application JARs such with a PDX serialized domain class, the Gemfire server log may indicate the following exception:

[warning 2015/03/11 10:54:15.343 CST server-1 <ServerConnection on port 7901 Thread 45> tid=0xd2] Exception on server while executing function: TestCastFunction
com.gemstone.gemfire.cache.execute.FunctionException: java.lang.ClassCastException: customer.DataObjectClass cannot be cast to customer.DataObjectClass
 at com.gemstone.gemfire.internal.cache.tier.sockets.command.ExecuteFunction66.cmdExecute(ExecuteFunction66.java:275)
 at com.gemstone.gemfire.internal.cache.tier.sockets.command.ExecuteFunction70.cmdExecute(ExecuteFunction70.java:51)
 at com.gemstone.gemfire.internal.cache.tier.sockets.BaseCommand.execute(BaseCommand.java:174)
 at com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection.doNormalMsg(ServerConnection.java:809)
 at com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection.doOneMessage(ServerConnection.java:940)
 at com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection.run(ServerConnection.java:1153)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
 at com.gemstone.gemfire.internal.cache.tier.sockets.AcceptorImpl$1$1.run(AcceptorImpl.java:532)
 at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.ClassCastException: customer.DataObjectClass cannot be cast to customer.DataObjectClass
 at function.TestCastFunction.execute(TestCastFunction.java:54)
 at com.gemstone.gemfire.internal.cache.tier.sockets.command.ExecuteFunction66.executeFunctionaLocally(ExecuteFunction66.java:331)
 at com.gemstone.gemfire.internal.cache.tier.sockets.command.ExecuteFunction66.cmdExecute(ExecuteFunction66.java:261)
 ... 9 more

Root Cause

When deploying a new version of a PDX serialized domain class into a GemFire cluster while there is an operation, such as get from a client, the GemFire server will try to deserialize the PDX serialized object which is serialized by the previous version of domain class into the domain class form using the current new version of domain class. This will result in the above ClassCastException.

Solution

Presently, GemFire's hot deployment of application JARs is mainly targeted at function service execution classes and not PDX serialized domain class.

To work around this issue, you can set the attribute read-serialized to true on the <pdx> element in the cache.xml file on the server side. This will cause the GemFire server to return a PdxInstance to client when a PDX serialized object is deserialized instead of deserializing the object to a domain class.

On the client side, you can create PdxInstances using a PdxInstanceFactory(Document Reference).

For example:

// Cache configuration setting PDX read behavior 
<cache>
  <pdx read-serialized="true" />
  ...
</cache>

Reference:

  1. Deploying Application JARs to Pivotal GemFire Members.
  2. PDX Attributes.
  3. Programming Your Application to Use PdxInstances.
  4. High Level Steps for Using PDX Serialization.

Comments

Powered by Zendesk