views:

76

answers:

1

When using Scala RemoteActors I was getting a ClassNotFoundException that referred to scala.actors.remote.NetKernel. I copied someone else's example and added RemoteActor.classLoader = getClass.getClassLoader to my Actor and now everything works. Why is this necessary?

+3  A: 

Remote Actors use Java serialization to send messages back and forth. Inside the actors library, you'll find a custom object input stream ( https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk/src/actors/scala/actors/remote/JavaSerializer.scala ) that is used to serialize objects to/from a socket. There's also some routing code and other magic.

In any case, the ClassLoader used for remoting is rather important. I'd recommend looking up Java RMI if you're unfamiliar with it. In any case, the ClassLoader that Scala picks when serializing/deserializing actors is the one Located on RemoteActor which defaults to null.

This means that by default, you will be unhappy without specifying a ClassLoader ;).

If you were in an environment that controls classloaders, such as OSGi, you'd want to make sure you set this value to a classloader that has access to all classes used by all serialized actors.

Hope that helps!

jsuereth
Thank you for the thorough answer. Is there no way that Scala could pick a better default than null?
Craig P. Motlin
`null` is the platform default, as far as I know. Actually the `null` class loader refers to the "System class loader" setting up the Java runtime.
soc
Why isn't the system classloader ok?
Craig P. Motlin
Not 100% correct: it does not necessarily use the "System" class loader, it might actually use "bootstrap" depending on the call to "latestUserDefinedLoader". See: http://forums.sun.com/thread.jspa?threadID=5163767. You'll notice Scala actors uses a similar solution to the problem that requires you to set RemoteActor.classLoader.For a side note, wikipedia has a decent article on classLoading hierarchies: http://en.wikipedia.org/wiki/Java_Classloader
jsuereth