You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Deserialization of ListBuffer results in a non-mutable structure prone to throwing NoSuchElementException #5374
Something is amiss with deserialization of ListBuffer, as shown here:
import collection.mutable.ListBuffer
import java.io._
val baos = new ByteArrayOutputStream
val oos = new ObjectOutputStream(baos)
oos.writeObject( ListBuffer(1,2,3) )
val bais = new ByteArrayInputStream( baos.toByteArray )
val ois = new ObjectInputStream(bais)
val lb = ois.readObject.asInstanceOf[ListBuffer[Int]]
val lb2 = ListBuffer[Int]() ++= lb
lb2 ++= List(1) // All okay
lb ++= List(1) // Throws an exception for me
Not sure whether this is related to other deserialization bugs (e.g. #SI-5262).
Jed Wesley-Smith (jedws) said (edited on Jan 15, 2012 7:09:23 AM UTC):
From what I can tell the last0 field isn't being deserialized correctly. As the :: has custom deserialization (see ::.readResolve) when the ListBuffer is deserialized it holds the old last0 reference, but it needs to be updated to the correct one in start chain. This hypotheses is supported by the fact that length is indeed increased as expected.
OT but interesting, the code above does indeed throw an exception in the REPL, but not when compiled by SBT.
@axel22 said:
This is indeed due to list serialization. With the current implementation there, any object that is serialized and which has multiple fields with references into the same list will be inaccurately deserialized. While we could patch list buffers to fix this, a better solution would be to change the way lists are serialized, and avoid surprising behaviour in the future.
Activity
scabug commentedon Jan 13, 2012
Imported From: https://issues.scala-lang.org/browse/SI-5374?orig=1
Reporter: @Ichoran
Affected Versions: 2.9.1
See #5262
scabug commentedon Jan 15, 2012
Jed Wesley-Smith (jedws) said (edited on Jan 15, 2012 7:09:23 AM UTC):
From what I can tell the last0 field isn't being deserialized correctly. As the :: has custom deserialization (see ::.readResolve) when the ListBuffer is deserialized it holds the old last0 reference, but it needs to be updated to the correct one in start chain. This hypotheses is supported by the fact that length is indeed increased as expected.
OT but interesting, the code above does indeed throw an exception in the REPL, but not when compiled by SBT.
Also, verified that prepending does work.
scabug commentedon Jan 15, 2012
Jed Wesley-Smith (jedws) said:
Originally a StackOverflow question
scabug commentedon Jan 23, 2012
@axel22 said:
This is indeed due to list serialization. With the current implementation there, any object that is serialized and which has multiple fields with references into the same list will be inaccurately deserialized. While we could patch list buffers to fix this, a better solution would be to change the way lists are serialized, and avoid surprising behaviour in the future.