So I've been playing around with remote actors, and I've run into some difficulties with serialization exceptions. One of my message is an instance of a case class, which itself contains an instance of a list of Path classes. The Path class is defined as follows, and is essentially a collection of Point instances with a precomputed distance attribute:
class Point (xi:Int,yi:Int) {
val x: Int = 开发者_如何学编程xi
val y: Int = yi
// Determine distance to another point
def distanceTo(p:Point):Int={
val dx = (x - p.x).toDouble
val dy = (y - p.y).toDouble
sqrt(dx*dx + dy*dy).round.toInt
}
override def equals(arg0:Any) : Boolean = {
if (arg0.isInstanceOf[Point] && arg0.asInstanceOf[Point].x == x && arg0.asInstanceOf[Point].y == y) return true
false
}
}
class Path(p: List[Point]) {
val path: List[Point] = p
val length: Int = Point.pathLength(p)
}
While these class instances can be passed around with no issuse using normal actors, any attempt to send a message containing a List[Path] collection fails with java.io.NotSerializableException.
So what do I do? Do I need to define serialization methods for these classes? Is there a better practice for this purpose other than sending class instances over the wire?
Any help would be greatly appreciated -- there seems to be a real shortage of information and examples of the Scala remote actor stuff.
Why would you expect your Path class to be serializable? Only case classes are automatically serializable in Scala. You need to either attach a @serializable annotation to Path (and a @SerialVersionUID for safety), declare Path as extending java.io.Serializable or java.io.Externalizable, or make it a case class (thus getting serializability for free).
Try using the @serialized annotation to the classes. However be careful, I have a friend who has run into all sorts of issues with non-trivial serialized methods. Stay immutable and stay simple ;)
Argh -- I'm an idiot -- @serializable did the trick. It would have helped to actually have recompiled the file in question...
精彩评论