This discussion is archived
5 Replies Latest reply: Dec 22, 2010 7:44 AM by 824227 RSS

Add Externalizable implementation to an already Serializable class

824227 Newbie
Currently Being Moderated
Hi

I have a class that implements Serializable. It has methods "private void writeObject(ObjectOutputStream)" and "private void readObject(ObjectInputStream)". Everything works.

I need to change the class to implement Externalizable.
Can/should I just change the writeObject and readObject methods to "public void writeExternal(ObjectOutput)" and "public void readExternal(ObjectInput)"?
Or should I keep the writeObject and readObject methods and just add new new writeExternal and readExternal methods with the same implementation?

This article makes it sound like I can just have writeExternal() call writeObject() and have readExternal() call readObject().
http://java.sun.com/developer/technicalArticles/Programming/serialization/

Right now I like the idea of adding the methods and calling the existing methods. Any thoughts or corrections?

Thanks
  • 1. Re: Add Externalizable implementation to an already Serializable class
    824227 Newbie
    Currently Being Moderated
    Hi

    Update - since ObjectOutputStream implements ObjectOutput, it is easier to have writeObject() call writeExternal() so I have to move the implementation. Similar for ObjectInputStream and ObjectInput.

    If a class implements Externalizable, are the Serializable methods (writeObject() and readObject()) ignored because writeExternal() and readExternal() are used?

    Thanks.
  • 2. Re: Add Externalizable implementation to an already Serializable class
    jtahlborn Expert
    Currently Being Moderated
    >
    If a class implements Externalizable, are the Serializable methods (writeObject() and readObject()) ignored because writeExternal() and readExternal() are used?
    yes, writeObject and readObject will be completely ignored. also, if your impls of writeObject/readObject used any of the default methods (defaultReadObject,defaultWriteObject), you will need to handle that yourself in readExternal/writeExternal. basically, when you make an object Externalizable, you assume all responsibility for reading/writing the object.
  • 3. Re: Add Externalizable implementation to an already Serializable class
    824227 Newbie
    Currently Being Moderated
    Hi,

    I am seeing that objects written out when the object was just Serializable cannot be read now that the object is Externalizable.

    Error reading file='D:\Temp\JobSerializationTestRig0.ser'
    java.io.InvalidClassException: test.StaticMethodCallJob; Serializable incompatible with Externalizable
    at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:579)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1582)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
    at test.JobSerializationTestRig.readJob(JobSerializationTestRig.java:93)
    at test.JobSerializationTestRig.readJobs(JobSerializationTestRig.java:85)
    at test.JobSerializationTestRig.run(JobSerializationTestRig.java:47)
    at test.JobSerializationTestRig.main(JobSerializationTestRig.java:38)


    That is, I wrote out a test file with a serialized version of the class before I made my changes - when the class implemented Serializable but not Externalizable.
    Then I made my change to implement Externalizable.
    I kept the same serialVersionUID.
    Now it cannot read in the previous version of the serialized data.

    I see in java.io.ObjectStreamClass lines 576 to 581 that it checks for this situation (an Externalizable reading a Serializable) and disallows it.
              if ((serializable == localDesc.serializable) &&
              (externalizable != localDesc.externalizable))
              {
              throw new InvalidClassException(localDesc.name,
                   "Serializable incompatible with Externalizable");
              }

    Any ideas of a work around?

    Thanks.
  • 4. Re: Add Externalizable implementation to an already Serializable class
    jtahlborn Expert
    Currently Being Moderated
    i don't personally know of a way to make a single class which can be deserialized from both a Serialized form and an Externalized form. it may be possible with some advanced serialization mojo...

    one thing you could do (not necessarily recommended unless you really need to support this), is make a subclass of your class which is Externalizable, leaving the old implementation still Serializable. if you read an "old" version, you will get the parent class. any new instances you instantiate would be the new subclass. you might have to do various gymnastics (like making sure equals works symmetrically between the 2 types) to get this all to work throughout your system, but it could probably work.
  • 5. Re: Add Externalizable implementation to an already Serializable class
    824227 Newbie
    Currently Being Moderated
    I don't see any way around it. So I will write code to eliminate stored instances of the class from previous releases. They are not really needed anyway. Going forward the Externalizable version is correct. Thanks.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points