Serious regression with SerialVersionUID not being honoured under 2.11

206 views
Skip to first unread message

oxbow_lakes

unread,
Apr 30, 2014, 5:03:30 AM4/30/14
to scala...@googlegroups.com
I've reported this as I cannot believe that this is not a bug (https://issues.scala-lang.org/browse/SI-8549). In case I'm wrong, can people please tell me what I should be doing instead?

here is a demonstration:

Welcome to Scala version 2.10.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_45).
Type in expressions to have them evaluated.
Type :help for more information.

scala> Nil.getClass.getDeclaredField("serialVersionUID").get(null)
res0: Object = -8256821097970055419


But with 2.11

Welcome to Scala version 2.11.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_45).
Type in expressions to have them evaluated.
Type :help for more information.

scala> Nil.getClass.getDeclaredField("serialVersionUID").get(null)
java.lang.NoSuchFieldException: serialVersionUID
  at java.lang.Class.getDeclaredField(Class.java:1948)
  ... 32 elided

Nil is declared in the library like so:

@SerialVersionUID(0 - 8256821097970055419L)
case object Nil extends List[Nothing] 

Chris

Jason Zaugg

unread,
Apr 30, 2014, 11:09:03 AM4/30/14
to oxbow_lakes, scala-user
On Wed, Apr 30, 2014 at 11:03 AM, oxbow_lakes <oxbow...@gmail.com> wrote:
I've reported this as I cannot believe that this is not a bug (https://issues.scala-lang.org/browse/SI-8549). In case I'm wrong, can people please tell me what I should be doing instead?

Thanks for reporting, Chris. Indeed, this is a serious regression. Anyone who relies on Java serialization should consider waiting for 2.11.1.

In addition to reinstating the generation of the static field, we have to decide what to do for the standard library after shipping with the default SerialVersionUIDs in 2.10.0.

I'm trying to figure out the lesser of two evils for the standard library in that release.

  a) Amend the @SerialVersionUID annotations on all the classes to "lock in" the automatically generated one that we've shipped in 2.10.0, or
  b) Go back to the intended @SerialVersionUID.

The first option will make serialization between standard library 2.11.0 and 2.11.1 work. The second will make *some* serialization between 2.10.x and 2.11.1 work, in cases where we haven't intentionally made an incompatible change to serialization.

Given that one of the planned changes touched List (SI-8042 "Use Serialization Proxy Pattern in List") I would prefer a). Even though we haven't guaranteed serialization compatibility before, even between minor versions, we have been rightly criticised for not even knowing when things have changed. As part of the fix for this bug, I'm going to add tests for serialization format stability for the core collections classes.

-jason


Jason Zaugg
Software Engineer

Typesafe – Build reactive apps!
Twitter: @retronym

oxbow_lakes

unread,
May 1, 2014, 4:06:55 AM5/1/14
to scala...@googlegroups.com, oxbow_lakes
Whilst I sort-of agree, it has been argued before by the scala team (https://issues.scala-lang.org/browse/SI-5697) that serial IDs are not part of binary compatibility. Also note that for any non-trivial scala project which uses serialization, then doing a) is pretty useless unless all library dependencies (which include serialized classes) also follow this route. For example, if I'm using akka, an ActorRef is serializable (see SerializedActorRef at https://github.com/akka/akka/blob/master/akka-actor/src/main/scala/akka/actor/ActorRef.scala): they may have to do exactly the same. 

It seems unlikely that all my dependencies are going to run your "fixer" on their codebase, so it's really unlikely that my non-trivial scala project is actually going to end up being really binary+serialization-compatible for 2.11.1.

Given this is the case, if I was you, I would be tempted to say "binary compatibility does not include serialization ID guarantees" (and then run away)

Chris
Reply all
Reply to author
Forward
0 new messages