Problema classe Serializable

15 respostas
R

PessoALL, uma ajuda por gentileza.

Tenho uma classe;

public class Contatos implements Serializable { private String nome; private String tel; ...

Vou gravar os contatos em uma Lista e depois salvar a Lista em um arquivo.
Pois bem, feito isso, preciso recuperar a Lista e consequentemente os contatos.

Tenho alguns métodos referentes aos procedimentos acima e tals.

Quando tento recuperar a tal Lista, recebo a seguinte mensagem de erro;

Exception in thread "main" java.io.InvalidClassException: Contatos; local class incompatible: stream classdesc serialVersionUID = -3497249703791104392, local class serialVersionUID = 1 at java.io.ObjectStreamClass.initNonProxy(Unknown Source) ...

Já coloquei uma throws Exception no método que recupera a Lista e nada…

Alguma observação?

15 Respostas

leoramos

Cara, usa FileInputStream e ObjectInputStream… dá uma olhada nisso…
O que provavelmente tu tá fazendo, é que tu tá recuperando os dados do arquivo e não tá fazendo o type cast.
Cola o código de recuperação da lista aí pra ajudar :wink:
Abraço!

Naruffy

toda classe que implementa Serializable precisa ter um serialVersionUID

tipo

public class classe implements Serializable
{
     private static final long serialVersionUID = 3521616756309050292L;
}

O unico problema é que eu num sei qual o critério pra colocar nessa variavel, pois no eclipse ele coloca esse valor enorme automático xD

R

leoramos:
Cara, usa FileInputStream e ObjectInputStream… dá uma olhada nisso…
O que provavelmente tu tá fazendo, é que tu tá recuperando os dados do arquivo e não tá fazendo o type cast.
Cola o código de recuperação da lista aí pra ajudar :wink:
Abraço!

public List<Contatos> recuperaLista() throws Exception { FileInputStream recupera = new FileInputStream(arq); ObjectInputStream recuperaObj = new ObjectInputStream(recupera); List<Contatos> contato = (List<Contatos>) recuperaObj.readObject(); recuperaObj.close(); return contato; }

R

Naruffy:
toda classe que implementa Serializable precisa ter um serialVersionUID

public class classe implements Serializable { private static final long serialVersionUID = 3521616756309050292L; }

Já fiz isso e também não funcionou.

LPJava

vc está importando?

import java.io.*;
R

LPJava:
vc está importando?

import java.io.*;

Sim. :roll:

A

Então … coloca mais detalhes do código pra gente ver aí …
Vc está utilizando o ObjectInputStream/ObjectOutputStream ?
Tem alguma instância de objeto dentro código ?

E não precisa declarar uma variável serialVersionUID.

Vlw

R
Artur Drummond:
Então ... coloca mais detalhes do código pra gente ver aí ... Vc está utilizando o ObjectInputStream/ObjectOutputStream ? Tem alguma instância de objeto dentro código ?

E não precisa declarar uma variável serialVersionUID.

Vlw

import ...

public class ManipulaArquivo {
	private final String ARQ = "contatos.txt";
		
	public void salvaLista(List<Contatos> contato) throws IOException {
		//File arquivo = new File ("contatos.txt");
		FileOutputStream salva = new FileOutputStream (ARQ);
		ObjectOutputStream salvaObj = new ObjectOutputStream (salva);
		salvaObj.writeObject(contato);
		salvaObj.close();
	}
	
	public List<Contatos> recuperaLista() throws Exception {
		FileInputStream recupera = new FileInputStream(ARQ);
		ObjectInputStream recuperaObj = new ObjectInputStream(recupera);
		List<Contatos> contato = (List<Contatos>) recuperaObj.readObject();
		recuperaObj.close();
		return contato;
	}

}
import ...

public class Agenda {
	
	public static void main(String[] args) throws Exception {
		int op;
		Contatos cont = null;
		List<Contatos> listaContatos = new ArrayList<Contatos>();
		ManipulaArquivo ma = new ManipulaArquivo();
		do {
			op = Integer.parseInt(JOptionPane.showInputDialog(null, "<< ESCOLHA UMA OPÇÃO >> \n\n" +
																	"1. Adicionar contato \n" +
																	"2. Visualizar todos contatos \n" +
																	"3. Sair \n"));
			switch(op) {
			case 1: 
				cont = new Contatos(JOptionPane.showInputDialog(null, "Nome: "), 
										JOptionPane.showInputDialog(null, "Telefone: "));
				listaContatos.add(cont);
				ma.salvaLista(listaContatos);
				
			case 2: 
				ma.recuperaLista();
...
import ...

public class Contatos implements Serializable {
	private String nome;
	private String tel;
//getter e setters + alguns métodos que ainda não terminei devido a esse problema
leoramos

Duas coisas:
1- Dá um flush() depois do writeObject(). É a descarga das alterações no arquivo.
2- Esse problema de diferença de versão geralmente dá quando tu altera o formato do que está sendo serializado, é uma maneira de prevenir problemas de desserialização de objetos serializados antes da alteração de alguma classe. Tenta excluir teu arquivo .txt e dá um rebuild no teu projeto. Pode até deletar o serialVersionUID.
Abraço!

R

leoramos:
Duas coisas:
1- Dá um flush() depois do writeObject(). É a descarga das alterações no arquivo.
2- Esse problema de diferença de versão geralmente dá quando tu altera o formato do que está sendo serializado, é uma maneira de prevenir problemas de desserialização de objetos serializados antes da alteração de alguma classe. Tenta excluir teu arquivo .txt e dá um rebuild no teu projeto. Pode até deletar o serialVersionUID.
Abraço!

Vou tentar isso e depois posto aqui.

Obrigado!

R

leoramos:
Duas coisas:
1- Dá um flush() depois do writeObject(). É a descarga das alterações no arquivo.
2- Esse problema de diferença de versão geralmente dá quando tu altera o formato do que está sendo serializado, é uma maneira de prevenir problemas de desserialização de objetos serializados antes da alteração de alguma classe. Tenta excluir teu arquivo .txt e dá um rebuild no teu projeto. Pode até deletar o serialVersionUID.
Abraço!

De fato funcionou.
Obrigado!

Nesse momento eu estou gravando no arquivo uma Lista de Contatos.

Talvez eu altere e, em vez de salvar uma Lista, eu salvo o Contato direto no arquivo.

Que acham?
Mais prático ou não?

leoramos

Cara, eu não aconselho.
Pra falar bem a verdade, eu fiz isso que tu tá fazendo na faculdade, e usei um Vector.
E sim, mandava pra lista, depois gravava tudo.
Não vou te afirmar com certeza… mas acho que daí ele vai sobrescrever.
Não é nem questão de ser prático, é questão de recuperar os dados todos depois, acho que tu irias perdê-los (ou então eu não entendi tua pergunta).
Eu já ouvi li algo assim aqui no fórum, a frase não é minha, mas fica a dica:
“Se você precisa de um banco de dados, use um banco de dados.”

Abraço!

(Edit: Acho que não me expressei direito. Na verdade, acho que o único objeto que terás salvo será o último. Foi isso que eu quis dizer.)

R

Não entendi direito…

Até concordo com isso, mas estou fazendo aqui uma aplicação simples, só por aprendizado mesmo.

Alguém consegue confirmar se eu consigo ou não fazer dessa forma:
Criar um Contato, salvar na Lista e gravar a Lista no arquivo. Depois recuperar a Lista e escrever outro Contato no final da Lista
:?:

leoramos

É naquela linha que você estava fazendo.
A única diferença é que ANTES de jogar o objeto na lista, você tem que RECUPERAR a lista que está no arquivo e em seguida fechar o arquivo.
Depois disso, você joga o objeto na lista, e manda a lista de volta pro arquivo.
E não esquece do flush() hehe
Abraço!

R

Vou fazer aqui e ver no que dá :!:

Criado 24 de julho de 2008
Ultima resposta 25 de jul. de 2008
Respostas 15
Participantes 5