To serialise a class all members must also be serialisable. However consider -Xprint:jvm output of the anonymous new Serializable in trait A
final class anon$1 extends Object with java.io.Serializable {
def get(): Nothing = anon$1.this.$outer.i();
<synthetic> <paramaccessor> <artifact> private[this] val $outer: $line58.iw$A = _;
def <init>($outer: $line58.iw$A): <$anon: Object> = {
if ($outer.eq(null))
throw null
else
anon$1.this.$outer = $outer;
anon$1.super.<init>();
()
}
}
In particular note the member
<synthetic> <paramaccessor> <artifact> private[this] val $outer: $line58.iw$A = _;
The class of instance referenced by $outer is A, however trait A has not been declared as Serializable. Therefore serialisation of anonymous class referenced by Broken.factory fails.
On the other hand, consider -Xprint:jvm output of the anonymous new Serializable in object Works
final class anon$1 extends Object with java.io.Serializable {
def get(): Nothing = iw$Works.this.i();
def <init>(): <$anon: Object> = {
anon$1.super.<init>();
()
}
}
Notice there is no member (similar to $outer) that is not Serializable. Therefore serialisation of anonymous class referenced by Works.factory succeeds.
The fix is to make trait A serialisiable like so
trait A extends Serializable { ... }
however Java Object Serialization Specification warns
Serialization of inner classes (i.e., nested classes that are not
static member classes), including local and anonymous classes, is
strongly discouraged for several reasons. Because inner classes
declared in non-static contexts contain implicit non-transient
references to enclosing class instances, serializing such an inner
class instance will result in serialization of its associated outer
class instance as well.