Open
Description
Compiler version
3.3.6, 3.7.1
Minimized code
Lazy vals annotated with @threadUnsafe
do not honour the @transient
annotation:
case class Bar() {
@transient @threadUnsafe
lazy val value: Long = System.nanoTime()
}
While examining the compiler output should suffice to identify the issue, here's also a reproducer of this behaviour:
//> using scala 3.7.1
import java.io.*
import scala.annotation.threadUnsafe
// Serialize any object to a byte array
def serialize[T <: Serializable](obj: T): Array[Byte] = {
val byteArrayOutputStream = new ByteArrayOutputStream()
val objectOutputStream = new ObjectOutputStream(byteArrayOutputStream)
try {
objectOutputStream.writeObject(obj)
byteArrayOutputStream.toByteArray
} finally {
objectOutputStream.close()
byteArrayOutputStream.close()
}
}
// Deserialize from a byte array back to an object
def deserialize[T](bytes: Array[Byte]): T = {
val byteArrayInputStream = new ByteArrayInputStream(bytes)
val objectInputStream = new ObjectInputStream(byteArrayInputStream)
try {
objectInputStream.readObject().asInstanceOf[T]
} finally {
objectInputStream.close()
byteArrayInputStream.close()
}
}
case class Foo() {
@transient
lazy val value: Long = System.nanoTime()
}
case class Bar() {
@transient @threadUnsafe
lazy val value: Long = System.nanoTime()
}
@main def main() = {
val foo1 = Foo()
foo1.value // init lazy val
val foo2 = deserialize[Foo](serialize(foo1))
assert(foo1.value != foo2.value, "Foo#value is not transient")
val bar1 = Bar()
bar1.value // init lazy val
val bar2 = deserialize[Bar](serialize(bar1))
assert(bar1.value != bar2.value, "Bar#value is not transient")
}
Output
Exception in thread "main" java.lang.AssertionError: assertion failed: Bar#value is not transient
at scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
at Foo$package$.main(Foo.scala:50)
at main.main(Foo.scala:41)
Expectation
I expect that lazy vals annotated with both @threadUnsafe
and @transient
honour the annotation, or if that's not possible (for some reason) a compiler warning should be raised for illegal combination of annotations