EDITADO
Sinistro o bagulho pessoal. Tô fazendo uma classe pra facilitar serialização. Tem uma classe abstrata Serializer e duas implementações, uma delas é XMLSerializer.
O problema é o seguinte: eu serializei um objeto para XML, depois abri o arquivo e mudei o nome da classe, depois tentei desserializar. O objetivo era testar se a classe ia fazer o comportamento certo, que seria retornar null e guardar a exception lançada. Mas isso não acontece. Nessa implementação que usa java.beans.XMLDecoder, ao chamar o readObject() desta classe é lançada uma ClassNotFoundException.
Até aí tudo bem, mas o método não tem a exceção na assinatura (se faz parte), e o catch simplesmente não funciona!!!
Arguém majuda faizfavôr!!!
Classe probemárdiga XMLSerializer:
package common.serialize;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class XMLSerializer<T> extends Serializer<T> {
public XMLSerializer(String fileName) {
super(fileName);
}
public XMLSerializer(File file) {
super(file);
}
@Override
protected void serialize(T obj, OutputStream os) {
XMLEncoder xe = new XMLEncoder(os);
xe.writeObject(obj);
xe.close();
}
@SuppressWarnings("unchecked")
@Override
protected T deserialize(InputStream is)
throws IOException, ClassNotFoundException {
T result = null;
XMLDecoder xd = new XMLDecoder(is);
// DÁ PAU AQUI!!!!!!! GERA ClassNotFoundException
// NEM ADIANTA TRATAR, DIZ QUE NUNCA LANÇA, MAS LANÇA!!!
result = (T) xd.readObject();
xd.close();
return result;
}
}
Essa classe aqui é a classe abstrata Serializer, não sei se ela teria algo errado:
package common.serialize;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
// This class uses Generics for avoiding unsafe casts on the read() calls.
public abstract class Serializer<T> {
private File file;
private Exception lastError;
public Serializer(String fileName) {
this(new File(fileName));
}
public Serializer(File file) {
this.file = file;
}
public boolean succeeded() {
return lastError == null;
}
public Exception lastError() {
return lastError;
}
public String lastErrorMessage() {
return succeeded()? null : lastError.getMessage();
}
// lastError will always be null whenever the (de)serialization
// executes successfully, and always non-null otherwise.
// This method should be synchronized?
public boolean write(T obj) {
try {
FileOutputStream fos = new FileOutputStream(file);
serialize(obj, fos);
fos.close();
lastError = null;
return true;
} catch (IOException e) {
lastError = e;
return false;
}
}
public T read() {
T result = null;
try {
FileInputStream fis = new FileInputStream(file);
result = (T) deserialize(fis);
fis.close();
lastError = null;
// APELEI PARA THROWABLE E NADA!
} catch (Throwable e) {
lastError = new Exception(e);
}
return result;
}
protected abstract void serialize(T obj, OutputStream os)
throws IOException;
protected abstract T deserialize(InputStream is)
throws IOException, ClassNotFoundException;
}
Essa é a classe de teste:
package avancado.serializacao;
import common.Console;
import common.FileUtil;
import common.OptionParser;
import common.serialize.DefaultSerializer;
import common.serialize.Serializer;
import common.serialize.XMLSerializer;
public class Serializando {
private static final String ARQUIVO = "Serializando.txt";
public static void main(String[] args) {
Pessoa p;
OptionParser op = new OptionParser(args, "rx");
Serializer<Pessoa> serializer = op.optionGiven('x')?
new XMLSerializer<Pessoa>(ARQUIVO):
new DefaultSerializer<Pessoa>(ARQUIVO);
if (op.optionGiven('w')) {
p = new Pessoa("Renato", 22, 58.0f);
Console.puts(serializer.write(p)?
"Escrevi pessoa: " + p :
"Erro ao escrever: " + serializer.lastErrorMessage());
}
if (op.optionGiven('r')) {
p = serializer.read();
// read() == null não quer dizer erro!
Console.putss(serializer.succeeded()?
"Li pessoa: " + p :
"Erro ao ler: " + serializer.lastErrorMessage());
}
Console.puts(FileUtil.read(ARQUIVO));
}
}
Essa é a saída da classe de teste. Vejam que o XML aparece às vezes no meio das exceptions, isso parece código em multi-thread:
java.lang.ClassNotFoundException: avancado.serializacao.Pesdssdoa
Continuing ...
java.lang.NullPointerException: target should not be null
Continuing ...
java.lang.NullPointerException: target should not be null
Continuing ...
java.lang.NullPointerException: target should not be null
Continuing ...
java.lang.NullPointerException: target should not be null
Continuing ...
java.lang.NullPointerException: target should not be null
Continuing ...
java.lang.NullPointerException: target should not be null
Continuing ...
java.lang.NullPointerException: target should not be null
Continuing ...
Li pessoa: null
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.5.0_06" class="java.beans.XMLDecoder">
<object class="avancado.serializacao.Pesdssdoa">
<void property="idade">
<int>22</int>
</void>
<void property="nome">
<string>Renato</string>
</void>
<void property="peso">
<float>58.0</float>
</void>
</object>
</java>
Helpem me plis!