1
votes

I am following the basic example of scala object serialization. However, when running the below unit test

package mytest

import java.io.{ByteArrayOutputStream, ObjectOutputStream}

import org.scalatest.{Matchers, WordSpec}

class BasicSerializationSpec extends WordSpec with Matchers {

  @SerialVersionUID(123L)
  class TestRecord(var content: String) extends Serializable {
    override def toString = s"TestRecord($content)"
  }

  "A TestRecord" should {
    "be serializable" in {
      val oo = new ObjectOutputStream(new ByteArrayOutputStream())

      val tr = new TestRecord("42")

      oo.writeObject(tr)

      oo.close
    }
  }
}

I get an Exception:

org.scalatest.Assertions$AssertionsHelper java.io.NotSerializableException: at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348) at mytest.BasicSerializationSpec.$anonfun$new$2(BasicSerializationSpec.scala:20)

I have tried to explicitly set the type

val tr : java.io.Serializable = new TestRecord("42")

But still no luck.

How do I properly serialize a scala object to a java ObjectOutputStream?

This is not a duplication of other stack answers because I am clearly extending Serializable with my class declaration.

Thank you in advance for your consideration and response.

1

1 Answers

5
votes

Serializing inner classes is a minefield in both Java and Scala, but provided that in your real code there are no references to BasicSerializationSpec's members in TestRecord, you should be able to make this work by adding a final modifier to the inner class definition:

final class TestRecord(var content: String) extends Serializable {

In real code you're unlikely to be testing classes that you define inside your test class, but you may run into similar situations when testing inner classes.