Skip to content

Instantly share code, notes, and snippets.

@earldouglas
Created March 20, 2011 02:26
Show Gist options
  • Save earldouglas/877999 to your computer and use it in GitHub Desktop.
Save earldouglas/877999 to your computer and use it in GitHub Desktop.
Remotely load and register Akka Actor classes at runtime (see https://github.com/JamesEarlDouglas/akka-remote-class-loading)
package com.earldouglas.remoteakka
import akka.actor.Actor
import akka.actor.Actor._
case object Greeting
case class Jar(val bytes: Array[Byte])
case class RegisterRemote(val name: String, val className: String)
object Runner {
def main(args: Array[String]) {
remote.start("localhost", 2552)
remote.register("actorLoader", actorOf[ActorLoader])
}
}
class ActorLoader extends Actor {
import java.net.{URL, URLClassLoader}
var classLoader: URLClassLoader = _
val remoteJar = "file:remote.jar"
def receive = {
case jar: Jar =>
var fos = new java.io.FileOutputStream("remote.jar")
new java.io.PrintStream(fos).write(jar.bytes)
fos.close
classLoader = new URLClassLoader(Array(new URL(remoteJar)), Thread.currentThread().getContextClassLoader())
case registerRemote: RegisterRemote =>
val clazz = classLoader.loadClass(registerRemote.className)
val actorClass = classOf[Actor]
clazz match {
case actorClass => remote.register(registerRemote.name, actorOf(clazz.asInstanceOf[Class[Actor]]))
}
}
}
package com.earldouglas.remoteakka
import akka.actor.Actor
import akka.actor.Actor._
import java.io.FileInputStream
case class Jar(val bytes: Array[Byte])
case class RegisterRemote(val name: String, val className: String)
object Runner {
def main(args: Array[String]) {
val actorLoader = remote.actorFor("actorLoader", "localhost", 2552)
actorLoader !! remoteJar
actorLoader !! new RegisterRemote("remote1", "com.earldouglas.remoteakka.Hello")
actorLoader !! new RegisterRemote("remote2", "com.earldouglas.remoteakka.Hola")
val remote1 = remote.actorFor("remote1", "localhost", 2552)
remote1 ! Greeting
val remote2 = remote.actorFor("remote2", "localhost", 2552)
remote2 ! Greeting
}
def remoteJar: Jar = {
import java.io._
import java.nio.channels.FileChannel.MapMode._
val file = new File("remote.jar")
val fileSize = file.length
val stream = new FileInputStream(file)
val buffer = stream.getChannel.map(READ_ONLY, 0, fileSize)
val bytes = new Array[Byte](buffer.capacity)
buffer.get(bytes)
stream.close
new Jar(bytes)
}
}
case object Greeting
class Hello extends Actor {
def receive: Receive = {
case Greeting => println("hello")
}
}
class Hola extends Actor {
def receive: Receive = {
case Greeting => println("hola")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment