Community
Participate
Working Groups
Build ID: I20070625-1500 Steps To Reproduce: 1. make sure the "Serializable class without serialVersionUID" potential programming problem is set to "warning" or "error" in Eclipse (or project specific) preferences 2. create a new class like this: import java.io.Serializable; public abstract class A implements Serializable { } EXPECTED BEHAVIOUR: Eclipse should show a warning/error because A is serializable and does not define a serialVersionUID OBSERVED BEHAVIOUR: Eclipse does not show any warning/error. More information: The absence of any error/warning might lead to a programming problem as soon as you are defining a hierarchy of serializable classes (where any of the ancestor is abstract) and you want to make any of the leaf classes safe (with respect to serialization) in the long-term.
I don't think it makes sense to add a serial version UID to a abstract class. It can't be instantiated and therefore also not serializable. The concrete subclasses however should have a serial version UID. Moving to jdt.core for the last word.
I would agree with Martin. Basically, serialVersionUID is not an inherited property. So adding one on the abstract class is not going to buy anything for subtypes. For itself, as it cannot be instantiated, what is the point of defining one ? Also checked that subtypes are properly warned when missing serialVersionUID. e.g. import java.io.Serializable; abstract class A implements Serializable { } class X extends A {} // X should define a serialVersionUID Marking as INVALID. No further action planned.
Added SerialVersionUIDTests#test007
I do not agree with this. Once you deserialize a non-abstract serializable class that extends an abstract serializable class, the process of creating the instance of the deserialized object involves the initialization of the abstract class code, too. If you have A abstract, serializable B non-abstract, serializable, extends A when you de-serialize an instance of B, the deserialization process checks not only B serialVersionUID, but A's one, too! If A's serialVersionUID is not defined and A.class has changed, the JRE throws an InvalidClassException when trying to deserialize an instance of B, even if B does have a fixed serialVersionUID! I recently encountered this exact problem and it was not easy to solve.
Btw we had this discussion before: bug 116733, bug 94352 and probably more
Try this. Given the following classes: --- import java.io.Serializable; public abstract class A implements Serializable { public void a() { System.out.println("a"); } } public class B extends A { private static final long serialVersionUID = -4759527637665705469L; public void b() { System.out.println("b"); } } import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; public class WriteTest { public static void main(String[] args) throws FileNotFoundException, IOException { B b = new B(); ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(new File(System .getProperty("user.home"), "b.bin"))); out.writeObject(b); out.flush(); out.close(); } } import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.ObjectInputStream; public class ReadTest { public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException { ObjectInputStream in = new ObjectInputStream(new FileInputStream(new File(System .getProperty("user.home"), "b.bin"))); final B b = (B) in.readObject(); b.b(); in.close(); } } --- Run WriteTest. Then run ReadTest: you should see "b" on the console. Then modify A so that it then is: import java.io.Serializable; public abstract class A implements Serializable { public void a() { System.out.println("a"); } public void aa() { System.out.println("aa"); } } Run ReadTest again: Exception in thread "main" java.io.InvalidClassException: A; local class incompatible: stream classdesc serialVersionUID = 3944066497804655483, local class serialVersionUID = 7050343047014399967 at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:546) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1552) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1466) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1552) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1466) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1699) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1305) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:348) at ReadTest.main(ReadTest.java:16)
Due to my comment #6, I think this bug is not invalid, so I'm reopening it.
Created attachment 78311 [details] Proposed fix + updated regression tests
javac seems to have the same problem. See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6356530
Re: comment 6 I now believe you are right. Thanks for reopening the bug. Olivier - pls go ahead and fix it.
Created attachment 78341 [details] Proposed fix + updated regression tests (more tests) This patch simply fixes more regression tests.
Released for 3.4M2. Updated regression tests.
Verified for 3.4M2 using build I20070917-0010
*** Bug 225339 has been marked as a duplicate of this bug. ***