Java - изменение serialVersionUID двоичного сериализованного объекта
Несколько месяцев назад я сериализовал объект java.io.Serializable в файл. Теперь мне нужно прочитать содержимое, но с тех пор serialVersionUID изменился, и теперь я получаю сообщение об ошибке "несовместимость классов". Я точно знаю, что ни один из элементов данных не изменился, поэтому единственным препятствием является проверка serialVersionUID.
Есть ли способ отключить проверку или изменить serialVersionUID в двоичном файле?
ПОЯСНЕНИЯ
Этот вопрос предполагает, что я не могу редактировать источник. Есть ли способ, которым я могу взломать файл.class или, возможно, взломать сериализованный объектный файл (использовать шестнадцатеричный редактор и изменить значение с некоторым определенным смещением)?
4 ответа
В качестве хака вы можете сгенерировать serialVer, который, вероятно, использует ваш jvm, используя инструмент serialver:
serialver -classpath независимо от com.foo.bar.MyClass
Если затем вы вручную установили serialVerUID в своем классе, он должен совпадать, и вы должны иметь возможность загружать, предполагая, что вы не изменили класс таким образом, чтобы сделать его недействительным.
Почему бы не изменить serialVersionUID в текущей версии, как описано в документации по сериализации?
Недавно я оказался в похожей ситуации - у меня было несколько сериализованных объектов, которые мне нужно было прочитать, serialVersionUID
из этих объектов отличается от самой новой версии, и, в моем случае, было несколько разных serialVersionUID
хранятся в файле для одного и того же класса (очевидно, в разное время). Таким образом, у меня не было роскоши изменять класс и устанавливать его serialVersionUID
; Я действительно должен был войти и изменить сохраненные данные.
Что я понял (прочитав исходный код java.io), так это то, что объект сериализуется при первом сохранении имени класса (используя writeUTF()
), а затем сразу после использования writeLong()
чтобы сохранить serialVersionUID
,
Мое решение состояло в том, чтобы перехватить исключение, затем вернуться, найти имя класса и сразу после имени заменить старое. serialVersionUID
с новым.
Документально подтверждено, что сериализация не предназначена для использования для сохранения данных. Чтобы получить эти данные обратно, вам необходимо понизить версию JVM до версии, которая использовалась для вывода этих данных.
Для дальнейшего использования не используйте сериализацию для сохранения данных между сеансами JVM.