Java - Изменение serialVersionUID двоичного сериализованного объекта

StackOverflow https://stackoverflow.com/questions/444909

Вопрос

Несколько месяцев назад я сериализовал объект java.io.Serializable в файл.Теперь мне нужно прочитать содержимое, но с тех пор serialVersionUID изменился, и теперь я получаю ошибку "несовместимый класс".Я точно знаю, что ни один из элементов данных не изменился, поэтому единственным препятствием является проверка serialVersionUID .

Есть ли способ либо отключить проверку, либо изменить serialVersionUID в двоичном файле?

РАЗЪЯСНЕНИЕ

Этот вопрос предполагает, что я не могу редактировать исходный код.Есть ли способ, которым я могу взломать файл .class или, возможно, взломать сериализованный объектный файл (используйте шестнадцатеричный редактор и измените значение с некоторым определенным смещением)?

Это было полезно?

Решение

В качестве взлома вы можете сгенерировать serialVer, который, вероятно, использует ваша jvm, с помощью инструмента serialver:

serialver - путь к классу независимо от com.foo.bar.MyClass

Если вы затем вручную установите serialVerUID в своем классе, он должен соответствовать, и вы должны иметь возможность загружать, предполагая, что вы не изменили класс таким образом, чтобы сделать его недействительным.

Другие советы

Почему бы вместо этого не изменить serialVersionUID в вашей текущей версии, как описано в Сериализация документация?

Недавно я оказался в похожей ситуации - у меня было несколько сериализованных объектов, которые я должен был прочитать, serialVersionUID один из этих объектов отличался от новейшей версии, и, в моем случае, было несколько разных serialVersionUIDs хранятся в файле для одного и того же класса (очевидно, хранятся в разное время).Таким образом, у меня не было роскоши изменять класс и устанавливать его serialVersionUID;На самом деле мне пришлось зайти и изменить сохраненные данные.

Что я выяснил (прочитав java.io исходный код), так это то, что объект сериализуется путем первого сохранения имени класса (используя writeUTF()), а затем сразу после использования writeLong() чтобы спасти serialVersionUID.

Мое решение состояло в том, чтобы перехватить исключение, затем вернуться назад, найти имя класса и сразу после имени класса заменить старое serialVersionUID с новым.

Документально подтверждено, что сериализация не предназначена для использования с сохраняемыми данными.Чтобы вернуть эти данные, вам нужно будет понизить вашу версию JVM до версии, которая использовалась для вывода этих данных.

На будущее, не используйте сериализацию для сохранения данных между сеансами JVM.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top