InvalidClassException: <class>; incompatible types for field <fieldname>

Viewed 6502

I am getting some sporadic exceptions when making polling RMI calls from one VM to another. The classpaths look consistent between VMs. I am using 64 bit java - the jres are consistent (jdk/v1.6.0_23-64bit). There is an inconsistency in the -XX:+UseCompressedOops flag & -XX:+UseConcMarkSweepGC between the VMs, but I am not aware if either could be a root cause?

Calling (client) VM has -XX:+UseCompressedOops & -XX:+UseConcMarkSweepGC set, server VM on which the getStatistics() call is made does not.

Couple points to note:-

  1. After encountering the exception, subsequent calls between the same VMs are ok over a period of days - i.e. the Invalid ClassException is a transient issue.

  2. [class] and [fieldname] vary each time the exception is encountered where exception is java.io.InvalidClassException: [class]; incompatible types for field [fieldname]

Is there any problem with making RMI calls (serialization) from a 64 bit VM with -XX:+UseCompressedOops to a another 64bit VM that is not set up to use compressed oops?

The stack:

java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
    java.io.InvalidClassException: testserver.cluster.Status; incompatible types for field committed
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:173)
    at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:178)
    at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:132)
    at $Proxy14.getStatistics(Unknown Source)
    at testserver.rm.RM$Check.run(RM.java:1593)
Caused by: java.io.InvalidClassException: testserver.cluster.Status; incompatible types for field committed
    at java.io.ObjectStreamClass.matchFields(ObjectStreamClass.java:2210)
    at java.io.ObjectStreamClass.getReflector(ObjectStreamClass.java:2105)
    at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:602)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1582)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1582)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1582)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1582)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1582)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
    at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:306)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:155)
    ... 4 more

thanks for your help

5 Answers

Most likely it is a simple case of 2 different compiled versions of the same class. But sometimes that can be tough to track down. Check the following:

  • Make sure you have the same jar being used in both JVMs (do binary diff on them)
  • Make sure you don't have multiple versions of the same jar in the classpath
  • If you are using an app server and have multiple apps deployed, each one uses its own classloader as well as the global one, so sometimes this can be in conflict.
Related