5 Replies Latest reply on Jan 16, 2006 6:15 AM by Bernd Ruecker

    Changes in serialized Objects

    Bernd Ruecker Master

      Hi all,

      I have a problem, not so jbpm related, but if anyone has a idea it would be very nice:

      We have a change in a class (one attribute type changes from String to CountryCode), so the serialized objects in the process can not be deserialized any more (ClassCastException).

      For this special case I have written a small tool, which deserializes all objects with our own "MyObjectInputStream" which overwrites
      Object resolveObject(Object obj)
      to return a CountryCode if a 2-letter-Code String is given. But this only works in this special case.

      Now another big change is on its way: Has anybody a good idea to implement a deserializer. It should hook in if a attribute with a known name of a known class is deserialized so there we can write own code.

      Or is it too off topic here?

        • 1. Re: Changes in serialized Objects
          Rainer Alfoeldi Novice

          Hi Bernd,

          isn't your current approach the solution? Java implements various classes that use readResolve() or readObject() to achieve deserialization of various implementations.

          This would have to be on a per class basis, i.e. every class that you change you have to know how to deserialize different versions but the specifc class would be the right place to put this knowledge anyway, wouldn't it?

          Greetings

          Rainer
          ------------------------------------------------------------------------------
          "Working on Sundays is a major cause for disfunctional marriages." :-)

          • 2. Re: Changes in serialized Objects
            Alejandro Guizar Master

            Just to elaborate on the subject, you don't need to subclass ObjectInputStream, just implement one of the special methods for custom deserialization as described in the javadoc for Serializable.

            • 3. Re: Changes in serialized Objects
              Alejandro Guizar Master

               

              "RAlfoeldi" wrote:
              Working on Sundays is a major cause for disfunctional marriages

              That's why I'm not getting married, ever. Viva la vie boheme!

              • 4. Re: Changes in serialized Objects
                Rainer Alfoeldi Novice

                See we're all here on Sunday... gotta change my life!

                @Bernd: java.util.Calendar is a good example of an implementation.

                The serialization pattern changed between JVMs but Sun had to make the backward compaitable. The answer was a standard writeObject() method and a readObject() method that decide if the old version was coming or a new one, which is basically the problem you want to solve.

                /**
                 * Reconstitutes this object from a stream (i.e., deserialize it).
                 */
                 private void readObject(ObjectInputStream stream)
                 throws IOException, ClassNotFoundException
                 {
                 final ObjectInputStream input = stream;
                 input.defaultReadObject();
                
                 stamp = new int[FIELD_COUNT];
                
                 // Starting with version 2 (not implemented yet), we expect that
                 // fields[], isSet[], isTimeSet, and areFieldsSet may not be
                 // streamed out anymore. We expect 'time' to be correct.
                 if (serialVersionOnStream >= 2)
                 {
                 isTimeSet = true;
                 if (fields == null) fields = new int[FIELD_COUNT];
                 if (isSet == null) isSet = new boolean[FIELD_COUNT];
                 }
                 else if (serialVersionOnStream >= 0)
                 {
                 for (int i=0; i<FIELD_COUNT; ++i)
                 stamp = isSet ? COMPUTED : UNSET;
                 }
                
                 serialVersionOnStream = currentSerialVersion;
                
                 // If there's a ZoneInfo object, use it for zone.
                 try {
                 ZoneInfo zi = (ZoneInfo) AccessController.doPrivileged(
                 new PrivilegedExceptionAction() {
                 public Object run() throws Exception {
                 return input.readObject();
                 }
                 });
                 if (zi != null) {
                 zone = zi;
                 }
                 } catch (Exception e) {
                 }
                
                 // If the deserialized object has a SimpleTimeZone, try to
                 // replace it with a ZoneInfo equivalent (as of 1.4) in order
                 // to be compatible with the SimpleTimeZone-based
                 // implementation as much as possible.
                 if (zone instanceof SimpleTimeZone) {
                 String id = zone.getID();
                 TimeZone zi = TimeZone.getTimeZone(id);
                 if (zi != null && zi.hasSameRules(zone) && zi.getID().equals(id)) {
                 zone = zi;
                 }
                 }
                 }


                • 5. Re: Changes in serialized Objects
                  Bernd Ruecker Master

                  Good starting point. Thanks a lot Rainer...