Java - modificando serialVersionUID do objeto serializado binário
-
22-07-2019 - |
Pergunta
Alguns meses atrás eu serializado um objeto java.io.Serializable em um arquivo. Agora eu preciso para ler o conteúdo, mas desde então o serialVersionUID mudou, e agora estou recebendo um erro "class incompatível". Eu sei para um fato que nenhum dos membros de dados mudaram, então a única barreira é a verificação de serialVersionUID.
Existe uma maneira de desativar a verificação ou modificar o serialVersionUID no arquivo binário?
ESCLARECIMENTO
Esta questão está supondo que eu não posso editar a fonte. Existe uma maneira que eu posso cortar o arquivo .class ou talvez cortar o arquivo objeto serializado (use um editor hexadecimal e alterar um valor em algum determinado offset)?
Solução
Como um hack, você pode gerar o serialver seu JVM está provavelmente usando usando a ferramenta serialver:
serialver -classpath qualquer que seja com.foo.bar.MyClass
Se você, em seguida, definir manualmente o serialVerUID em sua classe que deveria corresponder e você deve ser capaz de carga, supondo que você não mudaram a classe de tal forma um como para invalidar.
Outras dicas
Por que não modificar o serialVersionUID em sua versão atual em vez conforme descrito na serialização documentação?
Recentemente, me encontrei em uma situação similar - eu tinha alguns objetos serializados que eu tinha que ler, o serialVersionUID
desses objetos era diferente do que a versão mais recente e, no meu caso, havia um par de diferentes serialVersionUID
s armazenados na o arquivo para a mesma classe (armazenados em momentos diferentes, obviamente). Então eu não tenho o luxo de modificar a classe e definindo seu serialVersionUID
; Eu realmente tive que entrar e modificar os dados armazenados.
O que eu descobri (através da leitura do código fonte java.io) é que um objeto fica serializado pelo primeiro armazenar o nome da classe (usando writeUTF()
) e, em seguida, imediatamente após o uso writeLong()
para salvar o serialVersionUID
.
Minha solução foi capturar a exceção, em seguida, voltar, olhar para o nome da classe, e imediatamente após o nome da classe substituir o antigo serialVersionUID
com o novo.
Está documentado que serialização não se destina a ser usado para a persistência de dados. A fim de obter isso de volta os dados, você precisará fazer o downgrade sua versão do JVM para a versão que foi usado para a saída de dados.
Para referência futura, não usar serialização para persistir dados entre as sessões da JVM.