Skip to content
New issue

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

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enumeration not "resolved" when de-serialised #2214

Closed
scabug opened this issue Jul 30, 2009 · 14 comments
Closed

Enumeration not "resolved" when de-serialised #2214

scabug opened this issue Jul 30, 2009 · 14 comments
Assignees
Milestone

Comments

@scabug
Copy link

scabug commented Jul 30, 2009

I'm not quite sure of the intended behaviour here. I've been trying to serialise an Enumeration (in 2.7 and 2.8), but it doesn't seem to work as I expected.

Welcome to Scala version 2.8.0.r18405-b20090730020155 (Java HotSpot(TM) Client VM, Java 1.6.0_13).
Type in expressions to have them evaluated.
Type :help for more information.

scala> def serialise[T](t: T): T = {
     |   val buf = new java.io.ByteArrayOutputStream
     |   val out = new java.io.ObjectOutputStream(buf)
     |   out.writeObject(t)
     |   out.close
     |   val is = new java.io.ByteArrayInputStream(buf.toByteArray)
     |   val in = new java.io.ObjectInputStream(is)
     |   in.readObject.asInstanceOf[T]
     | }
serialise: [T](t: T)T

scala> object MyEnum extends Enumeration {
     |   val ONE = Value("1")
     |   val TWO = Value("2")
     | }
defined module MyEnum

scala> val a = MyEnum.ONE
a: MyEnum.Value = 1

scala> val b = serialise(a)
b: MyEnum.Value = 1

scala> println(a == b)
false

scala> println(System.identityHashCode(a))
1510253

scala> println(System.identityHashCode(b))
21353508

scala> println(System.identityHashCode(MyEnum))
15675004

scala> println(System.identityHashCode(serialise(MyEnum)))
8713829

After poking around in the (2.7) source a little, it seems that Value is being "resolved", but the actual Enumeration "MyEnum" object isn't (and why values end up non-equal too). I have a work-around - inserting def readResolve(): AnyRef = MyEnum method in MyEnum fixes it.

Should it be necessary that I provide my own readResolve method on each of my Enumeration objects? It's not really an issue, I just have quite a few in my object model, and I want to serialise the whole thing.

I just thought this was slightly unexpected behaviour, especially if you are used to Enum serialisation in Java. It is also something easily forgotten, and then enum values just end up unequal when you would probably expect they should be.

@scabug
Copy link
Author

scabug commented Jul 30, 2009

Imported From: https://issues.scala-lang.org/browse/SI-2214?orig=1
Reporter: Kieron Wilkinson (kieron)
See #5211

@scabug
Copy link
Author

scabug commented Jul 30, 2009

Kieron Wilkinson (kieron) said:
Doh. The reserialise should of course be serialise in the second-to-last line of the REPL session.

Thanks!

@scabug
Copy link
Author

scabug commented Sep 3, 2009

@oxbowlakes said:
I believe that you should just add the @serializable annotation to your MyEnum declaration

@scabug
Copy link
Author

scabug commented Sep 3, 2009

Kieron Wilkinson (kieron) said:
Thanks! That does indeed work.

However, it seems like a slightly odd thing to have to do given that Enumeration already has it defined. Or am I missing something?

@scabug
Copy link
Author

scabug commented Sep 3, 2009

@oxbowlakes said:
I've changed my mind - this is a bug. I can reproduce it via the program described on StackOverflow: http://stackoverflow.com/questions/1372346/scala-enumeration-and-readresolve.

@scabug
Copy link
Author

scabug commented Oct 26, 2009

@phaller said:
Fixed in r19301 (trunk).

@scabug
Copy link
Author

scabug commented Mar 18, 2010

@paulp said:
I'm reopening (assigning to myself, but anyone else please feel free) for the reasons described in #3186.

@scabug
Copy link
Author

scabug commented Mar 23, 2010

@phaller said:
(In r21235) Fixes #3186. Closes #2214.

@scabug
Copy link
Author

scabug commented Jun 29, 2010

@harrah said:
While looking into #3616, I noticed that the fix for this bug (in r21235) maintains a strong reference to every user-defined Enumeration. This is quite bad because as long as there are strong references to Scala library classes, user classes will not be garbage collected.

@scabug
Copy link
Author

scabug commented Jun 30, 2010

@paulp said:
Replying to [comment:10 harrah]:

While looking into #3616, I noticed that the fix for this bug (in r21235) maintains a strong reference to every user-defined Enumeration. This is quite bad because as long as there are strong references to Scala library classes, user classes will not be garbage collected.

How do you think we should address this? Would it be enough to use weak references and recreate the enum values if they're collected? It's not entirely clear to me how everything fits together.

@scabug
Copy link
Author

scabug commented Jun 30, 2010

@paulp said:
Actually: can't I treat this like another Symbol interning cache? Look, I wrote it to be reused:

/** This is private so it won't appear in the library API, but
  * abstracted to offer some hope of reusability.  */
private[scala] abstract class UniquenessCache[K, V >: Null]

IS THIS MY BIG CHANCE FOR REUSE?

@scabug
Copy link
Author

scabug commented Jul 1, 2010

@harrah said:
Weak references for keys and values should work:

private val emap = new WeakHashMap[Class[_], Reference[Enumeration]]

I'm not sure why the singleton isn't obtained with reflection, though:

val enum = getClass.getField("MODULE$$").get(null)

@scabug
Copy link
Author

scabug commented Jul 1, 2010

@paulp said:
(In r22463) Took a cue from mharrah that we don't need to build global static
data to keep track of something when we know where it's kept.
Altered the Enumeration deserialization scheme to use reflection, preserving
the singleton property by delivering the MODULE$$ singleton. This solves
the GC issue and lets us drop synchronization to boot. Also added
some graceful failure for malformed Enumerations. All tests look good
but a second opinion is in order: closes #2214, review by phaller.

@scabug
Copy link
Author

scabug commented Jul 2, 2010

@harrah said:
Thanks. I appreciate the fast response.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants