3

Consider the following Java exception classes:

public class BarException extends RuntimeException {
    // [...]
}

public class FooException extends BarException {
    private static final long serialVersionUID = -5322002268075295537L;

    // [...]
}

If I wish to update the inheritance hierarchy to remove BarException, such that FooException derives directly from RuntimeException, does this require a change to the serialVersionUID value?

// FooException with updated inheritance hierarchy
public class FooException extends RuntimeException {
    private static final long serialVersionUID = ???;

    // [...]
}
Etienne Neveu
  • 12,604
  • 9
  • 36
  • 59
Daniel Fortunov
  • 43,309
  • 26
  • 81
  • 106

4 Answers4

5

Yes. "Moving classes up or down the hierarchy" will cause incompatibility with previous serialized instances, as per the serialization spec.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
2

The Java 1.5 Serialization Specification suggests that removing classes from the inheritance hierarchy is a compatible change, so a change to serialVersionUID should not be required.

Any extra information in the serialization stream pertaining to BarException would be ignored when deserializing to the new FooException (which is derived directly from RuntimeException).

Daniel Fortunov
  • 43,309
  • 26
  • 81
  • 106
  • You're probably referring to the "Removing classes" point, but I think that only covers completely removing classes, not removing them from inside the inheritance tree while keeping subclasses - it's a case of "Moving classes up or down the hierarchy" – Michael Borgwardt Sep 14 '09 at 11:29
  • There is in a method for handling reading an object with a missing class - `readObjectNoData`. – Tom Hawtin - tackline Sep 14 '09 at 12:04
  • I'm not sure that the spec is entirely consistent. Deleting a field is not okay, but an entire class is? – Tom Hawtin - tackline Sep 14 '09 at 12:05
  • It's a bit strange - removing a class necessarily means removing or changing all fields using that type. And I can't find "changing a (non-primitive) field's type" in either the compatible or the incompatible list. – Michael Borgwardt Sep 14 '09 at 13:04
2

Given that the specification is unclear enough to cause confusion and debate, with no clear answer emerging, the only option left is to trust empirical evidence.

Taking the examples from the question above, of FooException deriving from BarException deriving from RuntimeException, and then removing BarException from the inheritance chain, I put together a sample application to try serialization and de-serialization in various combinations.

I get the following results:

As long as I keep the serialVersionUID unchanged, I can successfully serialize and deserialize the original FooException as the updated FooException, and vice versa.

The following caveats apply:

  • I am using JDK 1.5.0_07, and have not tried this on any other versions.
  • FooException has members of type int and Exception, which are successfully deserialized.
  • BarException adds no additional members to RuntimeException.
Daniel Fortunov
  • 43,309
  • 26
  • 81
  • 106
0

Technically yes, but it depends on whether your system persists serialized objects and if you control how the new, refactored code is deployed.

If you don't do persistence and you will refresh the entire deployment with the new version of the code, I don't see the need to change the serialVersionUID.

SteveD
  • 5,396
  • 24
  • 33
  • Hi Steve. As noted in the update to my question, "As long as I keep the serialVersionUID unchanged, I can successfully serialize and deserialize the original FooException as the updated FooException, and vice versa." This change does not seem to break serialization compatibility, so even if the system is persisting serialized objects, and I don't refresh the entire deployment at once, should I still change the serialVersionUID? – Daniel Fortunov Sep 18 '09 at 09:22
  • Short answer is I'm unsure - why not test it? I find the standard Java serialization brittle and it wouldn't surprise me if this worked (or even if it didn't)! – SteveD Sep 18 '09 at 10:00