Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Fix for SerialVersionUID instability. #1673

Merged
merged 4 commits into from Dec 3, 2012

Conversation

Projects
None yet
4 participants
Contributor

paulp commented Nov 26, 2012

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.

@paulp paulp 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.
4267444
Contributor

paulp commented Nov 26, 2012

Opened against master because it's presumably binary-incompatible.

Contributor

paulp commented Nov 26, 2012

Review by anyone with a clue about serialization. @jsuereth, @lrytz ?

paulp added some commits Nov 26, 2012

@paulp paulp Eliminate some one-arg asserts.
The only thing more fun than debugging non-deterministic
scaladoc crashes unrelated to one's change is doing so with
all one-argument asserts.
a854529
@paulp paulp Account for existence of scala's ClassfileAnnotation.
Apparently this thing is not real well tested, as the
scaladoc code was written as if it does not exist.
5573281
Contributor

paulp commented Nov 26, 2012

PLS REBUILD ALL

@paulp paulp Disabled part of a test.
Hmmm, the giant blob of binary data embedded in a test
suddenly stopped working. What does one do in this spot.
b9e01a0
Contributor

paulp commented Nov 30, 2012

Okay, review by @harrah, you must know something about serialization.

Contributor

harrah commented Nov 30, 2012

LGTM

@paulp paulp added a commit that referenced this pull request Dec 3, 2012

@paulp paulp Merge pull request #1673 from paulp/serialversionuid
Fix for SerialVersionUID instability.
4b2330b

@paulp paulp merged commit 4b2330b into scala:master Dec 3, 2012

@retronym retronym added a commit to retronym/scala that referenced this pull request May 5, 2014

@retronym retronym SI-8459 Honour the @SerialVersionUID annotatation
In PR #1673 / 4267444, the annotation `SerialVersionId` was
changed from a `StaticAnnotation` to `ClassFileAnnotation` in
order to avoid silently ignoring non-literal UIDs like:

    @SerialVersionUID(0 - 12345L) class C

And to flag non-constant UIDs:

    @SerialVersionUID("!!!".length)

While this indeed was fold constants, the change was incomplete.
The compiler API for reading the argument from a `ClassFileAnnoation`
is different, on must look for a `LiteralAnnotArg`, rather than a
`Literal`.

This commit:

  - amends the backend accordingly
  - removes relevant duplication between `GenASM` and `GenBCode`
  - tests that the static field is generated accordingly

This will mean that we will break deserialization of objects from
Scalal 2.11.0 that use this annotation.
6a1b863

@retronym retronym added a commit to retronym/scala that referenced this pull request May 5, 2014

@retronym retronym SI-8549 Honour the @SerialVersionUID annotatation
In PR #1673 / 4267444, the annotation `SerialVersionId` was
changed from a `StaticAnnotation` to `ClassFileAnnotation` in
order to avoid silently ignoring non-literal UIDs like:

    @SerialVersionUID(0 - 12345L) class C

And to flag non-constant UIDs:

    @SerialVersionUID("!!!".length)

While this indeed was fold constants, the change was incomplete.
The compiler API for reading the argument from a `ClassFileAnnoation`
is different, on must look for a `LiteralAnnotArg`, rather than a
`Literal`.

This commit:

  - amends the backend accordingly
  - removes relevant duplication between `GenASM` and `GenBCode`
  - tests that the static field is generated accordingly

This will mean that we will break deserialization of objects from
Scalal 2.11.0 that use this annotation.
ecbc9d0
Contributor

paulp commented May 7, 2014

Did "I didn't relish breaking every usage of scala's @serialversionuid in the known universe" win any prestigious irony awards?

Contributor

som-snytt commented May 7, 2014

"Known universe" was too restrictive a domain, so it was actually up for Understatement. But the other comment that "it's presumably binary-incompatible" won one of those technical awards they give out the day before the big event which no one attends except of a couple of stringers. I think the category was, "Irony in an observation that applies to everything except this." But next year they're starting a special category to recognize binary incompatibility; the statuette shows one hand washing another, with the inscription on the base: "mea paulpa."

@lrytz lrytz added a commit to lrytz/scala that referenced this pull request Nov 5, 2014

@lrytz lrytz SI-8960 Bring back the SerialVersionUID to anonymous function classes
In PR #1673 / 4267444, the annotation `SerialVersionId` was
changed from a `StaticAnnotation` to `ClassFileAnnotation` in
order to enforce annotation arguments to be constants.

The ID value in the AnnotationInfo moved from `args` to `assocs`, but
the backend was not adjusted. This was fixed in PR #3711 / ecbc9d0.

Unfortunately, the synthetic AnnotationInfo that is added to anonymous
function classes still used the old constructor (`args` instead of
`assocs`), so extracting the value failed, and no field was added to
the classfile.
93f646e

@lrytz lrytz added a commit to lrytz/scala that referenced this pull request Nov 5, 2014

@lrytz lrytz SI-8960 Bring back the SerialVersionUID to anonymous function classes
In PR #1673 / 4267444, the annotation `SerialVersionId` was changed
from a `StaticAnnotation` to `ClassFileAnnotation` in order to enforce
annotation arguments to be constants. That was 2.11.0.

The ID value in the AnnotationInfo moved from `args` to `assocs`, but
the backend was not adjusted. This was fixed in PR #3711 / ecbc9d0 for
2.11.1.

Unfortunately, the synthetic AnnotationInfo that is added to anonymous
function classes still used the old constructor (`args` instead of
`assocs`), so extracting the value failed, and no field was added to
the classfile.
fdf60bb

@lrytz lrytz added a commit to lrytz/scala that referenced this pull request Nov 5, 2014

@lrytz lrytz SI-8960 Bring back the SerialVersionUID to anonymous function classes
In PR #1673 / 4267444, the annotation `SerialVersionId` was changed
from a `StaticAnnotation` to `ClassFileAnnotation` in order to enforce
annotation arguments to be constants. That was 2.11.0.

The ID value in the AnnotationInfo moved from `args` to `assocs`, but
the backend was not adjusted. This was fixed in PR #3711 / ecbc9d0 for
2.11.1.

Unfortunately, the synthetic AnnotationInfo that is added to anonymous
function classes still used the old constructor (`args` instead of
`assocs`), so extracting the value failed, and no field was added to
the classfile.
21a44fe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment