Я играю с этим примером http://scala.sygneca.com/code/remoteactors , чтобы узнать, как работают удаленные актеры. в Scala (2.8.0). В частности, я немного изменил способ определения сообщений, отправляемых акторами, следующим образом:
sealed trait Event extends Serializable
case object Ping extends Event
case object Pong extends Event
case object Quit extends Event
и все работает, как ожидалось. К сожалению, если я определяю события как классы case вместо объектов case, как в:
sealed trait Event extends Serializable
case class Ping extends Event
case class Pong extends Event
case class Quit extends Event
, мой пример перестанет работать. Более подробно кажется, что, хотя объекты case являются сериализуемыми, классы case - нет. Действительно, когда я пытаюсь запустить свой пример с этой последней модификацией, я получаю следующее исключение:
scala.actors.remote.DelegateActor@148cc8c: caught java.io.NotSerializableException: scalachat.remote.Ping$
java.io.NotSerializableException: scalachat.remote.Ping$
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
at scala.actors.remote.JavaSerializer.serialize(JavaSerializer.scala:46)
at scala.actors.remote.NetKernel.namedSend(NetKernel.scala:38)
at scala.actors.remote.NetKernel.forward(NetKernel.scala:71)
at scala.actors.remote.DelegateActor$$anonfun$act$1$$anonfun$apply$1.apply(Proxy.scala:182)
at scala.actors.remote.DelegateActor$$anonfun$act$1$$anonfun$apply$1.apply(Proxy.scala:123)
at scala.actors.ReactorTask.run(ReactorTask.scala:34)
at scala.actors.ReactorTask.compute(ReactorTask.scala:66)
at scala.concurrent.forkjoin.RecursiveAction.exec(RecursiveAction.java:147)
at scala.concurrent.forkjoin.ForkJoinTask.quietlyExec(ForkJoinTask.java:422)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.mainLoop(ForkJoinWorkerThread.java:340)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:325)
Есть ли причина, по которой объекты case можно сделать сериализуемыми, а классы case - ' т? Есть ли способ заставить мой пример работать и с классами case?
Edit: как было предложено Виктором и подтверждено Аароном, я отправляю сопутствующий объект как сообщение вместо класса. Более того, при проверке скомпилированного кода с помощью javap становится очевидным, что, хотя класс является сериализуемым:
public class scalachat.remote.Ping extends java.lang.Object implements scalachat.remote.Event,java.io.Serializable,scala.ScalaObject,scala.Product
сопутствующий объект не является:
public final class scalachat.remote.Ping$ extends scala.runtime.AbstractFunction0 implements scala.ScalaObject
Теперь вопрос: как я могу указать, что я хочу использовать класс вместо сопутствующего объекта ? Я также добавил пустую пару скобок, когда отправляю сообщение, как предложил Аарон, например:
pong ! Ping()
, но ничего не изменилось. В конце концов, я также добавил фальшивый параметр в класс случая
case class Ping(i: Int) extends Event
, отправив сообщение как:
pong ! Ping(0)
, но по-прежнему не ощущая никакой разницы. Есть предложения?