title: How to deserialize an object persisted in a db now when the object has different serialVersionUID
body: <p>My client has an oracle data base and an object was persisted as a blob field via objOutStream.writeObject, the object now has a different <code>serialVersionUID</code> (even though the object has no change, maybe different jvm version) and when they try to de-serialize an exception is thrown:</p>
  
  <pre><code>java.io.InvalidClassException: CommissionResult; local class incompatible: 
   stream classdesc serialVersionUID = 8452040881660460728, 
   local class serialVersionUID = -5239021592691549158
  </code></pre>
  
  <p>They didn't assign a fixed value for <code>serialVersionUID</code> since the beginning so now that some thing changed that exception is thrown. Now they don't want to loose any data, to do so I think the best is  to read the objects, de-serialize them, and persist them again via XMLEncoder to avoid future errors like the current "class incompatible" error. </p>
  
  <p>Apparently there are 2 different values for the <code>serialVersionUID</code> persisted for that object so I want to read the data, try with one value and if it fails then try with the other value, To do so I've tried to change the <code>serialVersionUID</code> of the class using
  <a href="http://asm.ow2.org" rel="nofollow noreferrer">the ASM api</a>.  I've been able to change the value but the problem is how to make active the change upon the class so when it is de-serialized the <code>objInpStr.readObject()</code> take my modified version of the class with my specific <code>serializedVersionUID</code>. I made a test class to simulate the real environment, I take an object (which has as property the object with different <code>serialVersionUID</code> problem) the object name is <code>Reservation</code> the property is
  <code>CommissionResult</code>:</p>
  
  <pre><code>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();
      }
  </code></pre>
  
  <p>The test should fail with the <code>java.io.InvalidClassException</code> "local class incompatible"
  because I changed the <code>serialVersionUID</code> after I saved the file and used a new one to read
  de file but it doesn't fails so it means that the <code>ObjectInputStream.readObject</code> is not
  using my modified version of the <code>Reservation</code> class.</p>
  
  <p>Any Ideas? Thanks in advance.</p>
  
  <p>!!!!!!!!!!!!!UPDATE:</p>
  
  <p>Ok, it is possible to redefine the resultClassDescriptor to override the stream serialVersionUID, but, some thing strange happens, as I said before it seems there
  are 2 versions of the class persisted, objects with serialVersionUID = -5239021592691549158L and others with value 8452040881660460728L this last value is
  the one generated if I don't specify a value to the local class.</p>
  
  <p>-If I don't specify a value for the serialVersionUID then the default value (8452040881660460728L) is used, but is not possible to de-serealize the objects that
  has the other value, an error is thrown saying that a property is of an other type.</p>
  
  <p>-If I specify the value -5239021592691549158L then classes persisted with that value
  are successfully de-serialized, but not the others, same error of types.</p>
  
  <p>this  is the error trace  :</p>
  
  <p>Potentially Fatal Deserialization Operation. java.io.InvalidClassException: Overriding serialized class version mismatch: local serialVersionUID = -5239021592691549158 stream serialVersionUID = 8452040881660460728
  java.lang.ClassCastException: cannot assign instance of java.util.HashMap to field com.posadas.ic.rules.common.commisionRules.CommissionResult.statusCode of type java.lang.String in instance of com.posadas.ic.rules.common.commisionRules.CommissionResult</p>
  
  <p>When this error was thrown the class had the value of -5239021592691549158, if change
  the value to 8452040881660460728 the class is successfully de-serialized, so, what happens? why is that error that tries to cast for wrong class ?</p>
  
  <p>Thanks</p>