Запрос на Java-сериализацию

Я столкнулся с проблемой ниже, добавив новые методы-члены в существующий class Response implements Serializable{}. Неизвестный идентификатор серийной версии не указан. При нескольких попытках я получаю одинаковые серийные номера.

Error communicating with the webserver: com.abc.xyz.app.util.common.Response;
local class incompatible: stream classdesc serialversionUID = 
-3900355805473150430, local class serialversionUID = 
-6706527232726476603

После прохождения какой-либо документации я попытался изменить class Response на дополнительную строку: private final static long serialVersionUID = 1L;.

При этом изменении ниже приведена ошибка:

Error communicating with the webserver: com.abc.xyz.app.util.common.Response;
local class incompatible: stream classdesc serialversionUID = 
-3900355805473150430, local class serialversionUID = 1

Это классы, которые находятся в папке webapps tomcat и загружаются как xyz.jnlp на клиентской машине. Для загрузки xyz.jnlp с удаленного веб-сервера загружается машина с новым клиентом. Но все не работает!!!

Пожалуйста, помогите мне понять эту проблему.

Ответ 1

При сериализации объекта в поток записывается UID с последовательной версией класса. Если класс не имеет одного, он автоматически генерируется с использованием детерминированного алгоритма.

При десериализации объекта данного класса, UID последовательной версии локального класса (жестко закодированный или сгенерированный) сравнивается с идентификатором в потоке. И если они не совпадают, вы получаете исключение: это означает, что классы несовместимы.

Итак, чтобы исправить вашу проблему, у вас есть 2 варианта:

  • убедитесь, что сервер и клиент всегда используют один класс. Это лучшее, самое простое решение. Но это требует, чтобы все клиенты обновлялись каждый раз, когда сервер обновляется.
  • убедитесь, что классы всегда совместимы. Поскольку у вашего старого класса не было жестко закодированного serialVersionUID, и вы хотите изменить класс и поддерживать его совместимость, вам нужно жестко закодировать serialVersionUID со значением, которое идентично тому, которое было автоматически сгенерировано для начальной версии класс. И, конечно же, вы должны знать, что если вы добавите поля, получатель не сможет их прочитать, и если вы удалите поля, то значение получателя для этих полей будет равно NULL, что может нарушить инварианты.

Если вы не полностью понимаете последствия своих изменений, что сложно и требует чтения спецификации сериализации, я бы посоветовал пойти с вариантом 1: сохранить клиент и сервер до дат.