InvalidClassException: <class>; несовместимые типы для поля <fieldname> - PullRequest
13 голосов
/ 27 июля 2011

Я получаю некоторые спорадические исключения при выполнении запросов RMI от одной виртуальной машины к другой. Пути классов выглядят согласованно между виртуальными машинами. Я использую 64-битную Java - JRES согласованы (jdk / v1.6.0_23-64bit) . Существует несоответствие в -XX:+UseCompressedOops flag & -XX:+UseConcMarkSweepGC между виртуальными машинами, но я не знаю, может ли какая-либо из них быть основной причиной?

Вызывающая (клиентская) виртуальная машина имеет набор -XX:+UseCompressedOops & -XX:+UseConcMarkSweepGC, серверная виртуальная машина, на которой выполняется вызов getStatistics () , не выполняется.

Пара очков на заметку: -

  1. После возникновения исключения последующие вызовы между тем же Виртуальные машины исправны в течение нескольких дней, то есть недопустимое исключение ClassException это временная проблема.

  2. [класс] и [имя поля] меняются каждый раз, когда исключение встречается, где исключение java.io.InvalidClassException: [класс]; несовместимые типы для поле [имя поля]

Есть ли какие-либо проблемы с выполнением вызовов RMI (сериализация) с 64-битной ВМ с -XX:+UseCompressedOops на другую 64-битную ВМ, которая не настроена для использования сжатых операций?

стек:

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

спасибо за вашу помощь

Ответы [ 4 ]

0 голосов
/ 25 апреля 2016

Просто чтобы быть уверенным, что класс в обеих виртуальных машинах использует одну и ту же скомпилированную версию классов?Не могли бы вы попробовать перекомпилировать и добавить один и тот же файл jar на обе виртуальные машины.

Надеюсь, что уже позаботились.

0 голосов
/ 24 декабря 2014

Является ли эта опция (-XX: + UseCompressedOops) включенной по умолчанию для используемой виртуальной машины, если нет, я бы порекомендовал отключить ее и попробовать.

Может быть ошибка в используемом вами обновлении JRE, вы можете устранить его на форумах Oracle.

0 голосов
/ 28 декабря 2014

Обратите внимание, что -XX: + UseCompressedOops установлен по умолчанию с момента выпуска 6u23, даже если вы явно не отключили его.

Кроме того, эта опция влияет только на внутреннее представление указателей на оперативную память, которые не будут закодированы в сериализованном объекте, поэтому она не должна влиять на вызов RMI.

Держу пари, что проблема связана с некоторым байт-кодом, динамически создаваемым в памяти, который по какой-то причине еще не доступен при десериализации в первый раз. Это может быть в случае с библиотеками, такими как Hibernate и другими, которые оборачивают исходный класс новым пользовательским байт-кодом.

0 голосов
/ 27 июля 2011

Hmmh.Можно ли воспроизвести ситуацию с подключенным отладчиком?Имея точку останова на throw в ObjectStreamClass, где генерируется исключение:

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

Когда генерируется исключение, вы можете по крайней мере проверить getTypeCode возвращаемые значения.Я знаю, что это не решение, но может дать некоторые подсказки / более подробную информацию для включения в отчет об возможных ошибках.

...