Mein Client hat eine Oracle-Datenbank und ein Objekt wurde als Blob-Feld über objOutStream.writeObject beibehalten, das Objekt hat jetzt eine andere serialVersionUID
(obwohl hat das Objekt keine Veränderung, vielleicht verschiedene jvm Version) und wenn sie versuchen, eine Ausnahme deserialisieren geworfen:Wie ein Objekt deserialize in einer db jetzt, wenn das Objekt hat verschiedene serialVersionUID
java.io.InvalidClassException: CommissionResult; local class incompatible:
stream classdesc serialVersionUID = 8452040881660460728,
local class serialVersionUID = -5239021592691549158
sie nicht einen festen Wert für serialVersionUID
seit Anfang jetzt zugewiesen haben, so dass einige etwas geändert Diese Ausnahme wird ausgelöst. Jetzt wollen sie keine Daten verlieren, deshalb denke ich, dass das Beste darin besteht, die Objekte zu lesen, sie zu deserialisieren und sie über XMLEncoder wiederzuverwenden, um zukünftige Fehler wie den aktuellen "klasseninkompatiblen" Fehler zu vermeiden.
Offensichtlich gibt es 2 verschiedene Werte für die serialVersionUID
persisted für das Objekt, also möchte ich die Daten lesen, versuchen Sie mit einem Wert und wenn es fehlschlägt dann versuchen Sie mit dem anderen Wert, Um dies zu tun habe ich versucht, die ändern serialVersionUID
der Klasse mit the ASM api. Ich war in der Lage, den Wert zu ändern, aber das Problem ist, wie man die Änderung auf der Klasse aktivieren, so dass die objInpStr.readObject()
die modifizierte Version der Klasse mit meiner spezifischen serializedVersionUID
nehmen. Ich habe eine Testklasse die reale Umgebung zu simulieren, nehme ich ein Objekt (das als Eigenschaft hat das Objekt mit unterschiedlichem serialVersionUID
Problem) das Objekt Name ist Reservation
Eigentum ist CommissionResult
:
public class Reservation implements java.io.Serializable {
private CommissionResult commissionResult = null;
}
public class CommissionResult implements java.io.Serializable{
}
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.commons.SerialVersionUIDAdder;
public class SerialVersionUIDRedefiner extends ClassLoader {
public void workWithFiles() {
try {
Reservation res = new Reservation();
FileOutputStream f = new FileOutputStream("/home/xabstract/tempo/res.ser");
ObjectOutputStream out = new ObjectOutputStream(f);
out.writeObject(res);
out.flush();
out.close();
ClassWriter cw = new ClassWriter(0);
ClassVisitor sv = new SerialVersionUIDAdder(cw); //assigns a real serialVersionUID
ClassVisitor ca = new MyOwnClassAdapter(sv); //asigns my specific serialVerionUID value
ClassReader cr=new ClassReader("Reservation");
cr.accept(ca, 0);
SerialVersionUIDRedefiner loader= new SerialVersionUIDRedefiner();
byte[] code = cw.toByteArray();
Class exampleClass = loader.defineClass("Reservation", code, 0, code.length); //at this point the class Reservation has an especific serialVersionUID value that I put with MyOwnClassAdapter
loader.resolveClass(exampleClass);
loader.loadClass("Reservation");
DeserializerThread dt=new DeserializerThread();
dt.setContextClassLoader(loader);
dt.run();
} catch (Exception e) {
e.printStackTrace();
}}
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class DeserializerThread extends Thread {
public void run() {
try {
FileInputStream f2;
f2 = new FileInputStream("/home/xabstract/tempo/res.ser");
ObjectInputStream in = new ObjectInputStream(f2);
Reservation c1 = (Reservation)in.readObject();
System.out.println(c1);
} catch (Exception e) {
e.printStackTrace();
}
stop();
}
}
MyOwnClassAdapter Relevant code:
public void visitEnd() {
// asign SVUID and add it to the class
try {
cv.visitField(Opcodes.ACC_FINAL + Opcodes.ACC_STATIC,
"serialVersionUID",
"J",
null,
new Long(-11001));//computeSVUID()));
} catch (Throwable e) {
e.printStackTrace();
throw new RuntimeException("Error while computing SVUID for x"
, e);
}
super.visitEnd();
}
Der Test sollte mit fehlschlagen die java.io.InvalidClassException
„lokale Klasse unvereinbar“ , weil ich die serialVersionUID
geändert, nachdem ich die Datei gespeichert und verwendet eine neue de Datei zu lesen, aber es funktioniert nicht nicht so bedeutet dies, dass die ObjectInputStream.readObject
nicht meine modifizierte Version des Reservation
mit Klasse.
Irgendwelche Ideen? Danke im Voraus.
!!!!!!!!!!!!! UPDATE:
Ok, ist es möglich, das resultClassDescriptor neu zu definieren, um den Strom serialVersionUID außer Kraft zu setzen, aber, seltsam etwas, was geschieht, wie gesagt, bevor es scheint dort sind 2 Versionen der Klasse persistent, Objekte mit serialVersionUID = -5239021592691549158L und andere mit Wert 8452040881660460728L dieser letzte Wert ist der eine generiert, wenn ich keinen Wert für die lokale Klasse angeben.
-Wenn ich verwendet keinen Wert für die serialVersionUID angeben dann wird der Standardwert (8452040881660460728L), ist aber die Objekte de-serealize nicht möglich, die den anderen Wert hat, wird ein Fehler zu sagen, dass ein geworfen Eigentum ist von einem anderen Typ.
-Wenn ich den Wert -5239021592691549158L angeben, dann werden Klassen mit diesem Wert erfolgreich de-serialisiert, aber nicht die anderen, gleichen Fehler der Typen.
dies ist der Fehlertrace:
potenziell tödliche Deserialisierung Betrieb. java.io.InvalidClassException: Überschreiben der Uneinheitlichkeit der serialisierten Klassenversion: local serialVersionUID = -5239021592691549158 stream serialVersionUID = 8452040881660460728 java.lang.ClassCastException: dem Feld com.posadas.ic.rules.common.commisionRules kann keine Instanz von java.util.HashMap zugewiesen werden .CommissionResult.statusCode vom Typ java.lang.String in der Instanz von com.posadas.ic.rules.common.commisionRules.CommissionResult
Wenn diese Fehler die Klasse hatte den Wert von -5239021592691549158 geworfen wurden, wenn eine Änderung der Wert auf 8452040881660460728 wird die Klasse erfolgreich deserialisiert, so, was passiert? Warum ist dieser Fehler, der für die falsche Klasse zu sprechen versucht?
Dank
Hier bearbeiten und ersetzen ist eine ähnliche Frage http: //stackoverflow.com/questions/444909/java-modifying-serialversionuid-of-binary-serialized-object –
Ja, ich habe diese Frage schon einmal gelesen, aber ich habe keine Antwort gefunden. Daniel hat gesagt, dass er einen Weg gefunden hat, es zu lösen, aber er hat es nicht getan. Ich habe genau gesagt, was ich brauche, aber ich habe keine Möglichkeit gefunden, ihn zu fragen: S –