InvalidClassException:<class>; 字段<fieldname>的不兼容类型

a_g*_*a_g 15 java 64-bit serialization rmi

在从一个VM到另一个VM进行轮询RMI调用时,我遇到了一些零星的异常.类路径在VM之间看起来是一致的.我使用64位java - jres是一致的(jdk/v1.6.0_23-64bit).-XX:+UseCompressedOops flag & -XX:+UseConcMarkSweepGC虚拟机之间存在不一致,但我不知道是否可能是根本原因?

调用(客户端)VM已-XX:+UseCompressedOops & -XX:+UseConcMarkSweepGC设置,进行getStatistics()调用的服务器VM 不会.

情侣点注意: -

  1. 遇到异常后,相同VM之间的后续调用在一段时间内都可以正常 - 即Invalid ClassException是一个暂时性问题.

  2. 每次遇到异常时[class]和[fieldname]都会有所不同,其中异常是java.io.InvalidClassException:[class]; 字段[fieldname]的不兼容类型

64位虚拟机-XX:+UseCompressedOops到另一个未设置为使用压缩oops 的64位虚拟机进行RMI调用(序列化)是否有任何问题?

堆栈:

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
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助

mer*_*ter 0

嗯。附加调试器是否可以重现这种情况?在 ObjectStreamClass 中设置断点throw,抛出异常:

if ((f.isPrimitive() || lf.isPrimitive())
        && f.getTypeCode() != lf.getTypeCode()) {
    throw new InvalidClassException(localDesc.name,
        "incompatible types for field "
                    + f.getName());
}
Run Code Online (Sandbox Code Playgroud)

当抛出异常时,您至少可以检查getTypeCode返回值。我知道,这不是一个解决方案,但可能会提供一些线索/更多详细信息,以包含在可能的错误报告中。