From 426744441c22fa3153b7192bead46f8b244c4f12 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sun, 25 Nov 2012 18:29:16 -0800 Subject: Fix for SerialVersionUID instability. Can hardly believe this has been broken for a decade or so, but there it is - see test case. Four classes attempt to set their SerialVersionUID to 13. One succeeds. No warnings or errors. The output before this patch (for me anyway - your random numbers may differ) was: 860336111422349646 13 8409527228024057943 -7852527872932878365 There was already code in place for rejecting annotations with non-constant args when constant args are required, but that check is only performed on ClassfileAnnotations, and SerialVersionUID was a StaticAnnotation. Maybe people don't reach for ClassfileAnnotation because of this giant warning which I see no way to suppress: warning: Implementation restriction: subclassing Classfile does not make your annotation visible at runtime. If that is what you want, you must write the annotation class in Java. Why did I change the name of the field from uid to value? If you don't use the name 'value', you have to name the argument every time you use it, even if it's the only parameter. I didn't relish breaking every usage of scala's @SerialVersionUID in the known universe. --- src/library/scala/SerialVersionUID.scala | 2 +- test/files/neg/serialversionuid-not-const.check | 10 ++++++++++ test/files/neg/serialversionuid-not-const.scala | 16 ++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 test/files/neg/serialversionuid-not-const.check create mode 100644 test/files/neg/serialversionuid-not-const.scala diff --git a/src/library/scala/SerialVersionUID.scala b/src/library/scala/SerialVersionUID.scala index 1f7d047060..77094f0bbf 100644 --- a/src/library/scala/SerialVersionUID.scala +++ b/src/library/scala/SerialVersionUID.scala @@ -12,4 +12,4 @@ package scala * Annotation for specifying the `static SerialVersionUID` field * of a serializable class. */ -class SerialVersionUID(uid: Long) extends scala.annotation.StaticAnnotation +class SerialVersionUID(value: Long) extends scala.annotation.ClassfileAnnotation diff --git a/test/files/neg/serialversionuid-not-const.check b/test/files/neg/serialversionuid-not-const.check new file mode 100644 index 0000000000..9c383d97ad --- /dev/null +++ b/test/files/neg/serialversionuid-not-const.check @@ -0,0 +1,10 @@ +serialversionuid-not-const.scala:1: error: annotation argument needs to be a constant; found: 13L.toLong +@SerialVersionUID(13l.toLong) class C1 extends Serializable + ^ +serialversionuid-not-const.scala:3: error: annotation argument needs to be a constant; found: 13.asInstanceOf[Long] +@SerialVersionUID(13.asInstanceOf[Long]) class C3 extends Serializable + ^ +serialversionuid-not-const.scala:4: error: annotation argument needs to be a constant; found: Test.bippy +@SerialVersionUID(Test.bippy) class C4 extends Serializable + ^ +three errors found diff --git a/test/files/neg/serialversionuid-not-const.scala b/test/files/neg/serialversionuid-not-const.scala new file mode 100644 index 0000000000..f0e3ef4e7e --- /dev/null +++ b/test/files/neg/serialversionuid-not-const.scala @@ -0,0 +1,16 @@ +@SerialVersionUID(13l.toLong) class C1 extends Serializable +@SerialVersionUID(13l) class C2 extends Serializable +@SerialVersionUID(13.asInstanceOf[Long]) class C3 extends Serializable +@SerialVersionUID(Test.bippy) class C4 extends Serializable + +object Test { + val bippy = 13L + + def show(c: Class[_]) = println(java.io.ObjectStreamClass.lookup(c).getSerialVersionUID) + def main(args: Array[String]): Unit = { + show(classOf[C1]) + show(classOf[C2]) + show(classOf[C3]) + show(classOf[C4]) + } +} -- cgit v1.2.3