views:

74

answers:

3

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.

+1  A: 

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 ;)

jsuereth
grr -- I forgot -- I *did* add @serialization both classes. So I can actually to something like:val z = new Path ( List[Point](y) )output.writeObject(z)Where output is an ObjectOutputStrem instance. But when this gets sent as a message -- no dice. Same serialization error.
hayzeus
+2  A: 

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).

Dave Griffith
Sorry -- see comment to jsuereth -- no dice, even though it seems to work with ObjectOutputStream.writeObject.
hayzeus
+1  A: 

Argh -- I'm an idiot -- @serializable did the trick. It would have helped to actually have recompiled the file in question...

hayzeus