Erro com Serializable

Bom dia pessoal,

criei uma classe para ser serializada. Uma outra classe faz o papel de servidor e cliente, utilizando essa outra classe para ser Serializada e “De-Serializada”.

Colocando um JAR do servidor rodando em uma máquina com o Windows XP SP3 é gerado um arquivo TXT com os dados. Pegando o arquivo TXT e colocando em outra máquina com o Windows XP SP2 a hora que passa pelo método de “de-serialização” da a exception InvalidClassException.

Procurei em vários locais e descobri um possível motivo:serialVersionUID.

Até ai blz, mas tipo, quando eu adiciono ele, ou mudo para um serial QUALQUER… sempre da o mesmo erro, e na exception mostra sempre o mesmo serial para a classe LOCAL e para a classe que gerou o arquivo.

Não era pra mudar o serial da minha pelo menos quando eu troco o serialVersionUID ???

Não sei mais o que fazer.

Abaixo o inicio da minha classe.

public class DataTable extends JTable implements Serializable {
private static final long serialVersionUID = -1409978301911392970L;

Qual o trecho para serialização e para de-serialização? Poste aqui.

Este é o trecho de código onde é feito a serialização. É passado por parâmetro o objeto da classe que vai ser serializada e o local.
Abaixo o código que efetua o processo reverso.

Fiz alguns testes e notei o seguinte. Em 1 máquina aqui mesmo alterando o código Serial a mensagem de erro é sempre a mesma mas em outras 2 máquinas, o código serial quando dá erro é o código que está na classe.

private static void saveObjectSerializable(Object object,String fileName) { try { FileOutputStream fileOut = new FileOutputStream(System.getProperty("user.dir") + "\\" +fileName+".txt"); ObjectOutputStream objectOut = new ObjectOutputStream(fileOut); objectOut.writeObject(object); objectOut.flush(); objectOut.close(); objectOut.flush(); objectOut.close(); } catch(Exception e) { JOptionPane.showMessageDialog(null,e.toString()); } }

private static Object loadObjectSerializable(String fileName) { try { DataTable dt = new DataTable(); FileInputStream fileInp = new FileInputStream(fileName); ObjectInputStream objInp = new ObjectInputStream(fileInp); dt =(DataTable)objInp.readObject(); return dt; } catch(Exception e){e.printStackTrace(); JOptionPane.showMessageDialog(null,e.toString());} return null; }

É estranho não funcionar… tente serializar classes da API (como JFrame, ou JButton) e depois tente resgatá-las. Se der certo, o problema é com sua classe DataTable.

Agora, algumas sugestões para melhoria da classe:

1 - Por que os métodos flush() e close() são chamados duas vezes?

2 - Ao invés de tratar as exceções com try … catch é preferível usar o throws na assinatura do método pois deixa a classe mais genérica (reaproveitamento de código!!).

3 - Ainda quando ao reaproveitamento, não faça o cast dentro do método. Faça isso onde o método é chamado. Isso evita ter que criar um novo método para serializar outro tipo de objeto.

4 - Portabilidade: não use barra invertida para separar diretórios. Apesar de isso funcionar no Windows, em outros SOs não funciona (como no meu caso, que uso Linux). Use a barra comum que funciona em qualquer SO.

Com algumas mudanças, sua classe poderia ficar assim:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class ObjectIO {

	public static void writeSerializableObject(Object object, String fileName)
			throws IOException {
		FileOutputStream fileOut = new FileOutputStream(System
				.getProperty("user.dir")
				+ "/" + fileName);
		ObjectOutputStream objectOut = new ObjectOutputStream(fileOut);
		objectOut.writeObject(object);
		objectOut.flush();
		objectOut.close();
	}

	public static Object readSerializableObject(String fileName)
			throws IOException, ClassNotFoundException {
		FileInputStream fileInp = new FileInputStream(System
				.getProperty("user.dir") + "/"
				+ fileName);
		ObjectInputStream objInp = new ObjectInputStream(fileInp);
		return objInp.readObject();
	}

}

E uma classe de teste:

import java.io.IOException;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class TesteSerial {

	public static void main(String[] args) {
		// cria um JFrame
		JFrame f = new JFrame("Serialização");
		f.setSize(500, 500);
		f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		f.setLocationRelativeTo(null);
		// serializa o dito cujo
		try {
			ObjectIO.writeSerializableObject(f, "jframe.dat");
		} catch (IOException e) {
			JOptionPane.showMessageDialog(null, e);
			return;
		}
		// resgata-o e exibe
		try {
			JFrame a = (JFrame)ObjectIO.readSerializableObject("jframe.dat");
			a.setVisible(true);
		} catch (Exception e) {
			JOptionPane.showMessageDialog(null, e);
		}
	}
}

Com base nisso, faça as adaptações necessárias e verifique se o problema não está na classe a ser serializada.

Boa tarde Marco,

desde já agradeço por ter respondido. Fiz as alterações que vc me sugeriu. Fiz uns testes também quanto a serialização e tal e ainda continuo com o erro. Tipo assim, fiz o teste em 4 máquinas aqui. Em 3 funciona perfeitamente, quando altero o serial da classe que faz a leitura aparece os 2 seriais corretos (classe e arquivo) mas em 1 dessas máquinas não tem jeito cara. Alterei serial, fiz testes com o JDK 1.4 pois essa máquina tem… tentei instalar o JDK 1.4 em outras máquinas e nelas continuaram funcionando… exceto nessa máquina que é um notebook de um colega meu.

Tipo, esse notebook tem uns temas do windows vista e tal… e não sei a procedência do windows instalado nele… será que isso tem algo a ver? Acredito que agora não seja relacionado a código, e sim a algo naquela máquina. O que vc acha?

Pela situação, parece que o problema é com a máquina sim. Acho que o sistema operacional não influencia nesse caso (independente da procedência).

Talvez haja algum problema no JRE ou em algo que interfira na JVM. Tente desinstalar o JRE ou JDK completamente (isso inclui apagar manualmente alguma possível pasta que possa restar em C:\Arquivos de Programas\ após remover em Instalar ou Remover programas). Depois tente instalar novamente o JRE (se possível, a versão mais atual) e rodar de novo.

Se o erro persistir, sinto muito… acho que não terá outra solução: mande seu colega reinstalar o sistema se ele quiser usar o Java pra valer.