This content has been marked as final. Show 5 replies
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?
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.
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
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?
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...1 person found this helpful
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.
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.