diff --git a/akka-actor-tests/src/test/scala/akka/actor/ActorRefSpec.scala b/akka-actor-tests/src/test/scala/akka/actor/ActorRefSpec.scala index 035716ff1a..b88d54fb11 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/ActorRefSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/ActorRefSpec.scala @@ -13,6 +13,7 @@ import akka.testkit.Testing.sleepFor import java.lang.IllegalStateException import akka.util.ReflectiveAccess import akka.dispatch.{ DefaultPromise, Promise, Future } +import akka.serialization.Serialization import java.util.concurrent.{ CountDownLatch, TimeUnit } object ActorRefSpec { @@ -248,12 +249,35 @@ class ActorRefSpec extends AkkaSpec { out.flush out.close - val in = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray)) - val readA = in.readObject + Serialization.application.withValue(app) { + val in = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray)) + val readA = in.readObject - a.isInstanceOf[LocalActorRef] must be === true - readA.isInstanceOf[LocalActorRef] must be === true - (readA eq a) must be === true + a.isInstanceOf[LocalActorRef] must be === true + readA.isInstanceOf[LocalActorRef] must be === true + (readA eq a) must be === true + } + } + + "throw an exception on deserialize if no application in scope" in { + val a = createActor[InnerActor] + + import java.io._ + + val baos = new ByteArrayOutputStream(8192 * 32) + val out = new ObjectOutputStream(baos) + + out.writeObject(a) + + out.flush + out.close + + val in = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray)) + + (intercept[java.lang.IllegalStateException] { + in.readObject + }).getMessage must be === "Trying to deserialize a serialized ActorRef without an AkkaApplication in scope." + + " Use akka.serialization.Serialization.application.withValue(akkaApplication) { ... }" } "must throw exception on deserialize if not present in local registry and remoting is not enabled" in { @@ -287,10 +311,12 @@ class ActorRefSpec extends AkkaSpec { a.stop() latch.await(5, TimeUnit.SECONDS) must be === true - val in = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray)) - (intercept[java.lang.IllegalStateException] { - in.readObject - }).getMessage must be === "Trying to deserialize ActorRef [" + expectedSerializedRepresentation + "] but it's not found in the local registry and remoting is not enabled." + Serialization.application.withValue(app) { + val in = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray)) + (intercept[java.lang.IllegalStateException] { + in.readObject + }).getMessage must be === "Trying to deserialize ActorRef [" + expectedSerializedRepresentation + "] but it's not found in the local registry and remoting is not enabled." + } } "support nested createActors" in { diff --git a/akka-actor/src/main/scala/akka/actor/ActorRef.scala b/akka-actor/src/main/scala/akka/actor/ActorRef.scala index cf9e70b4b1..87cc55395d 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorRef.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRef.scala @@ -388,17 +388,22 @@ case class SerializedActorRef(uuid: Uuid, import akka.serialization.Serialization._ @throws(classOf[java.io.ObjectStreamException]) - def readResolve(): AnyRef = application.value.registry.local.actorFor(uuid) match { - case Some(actor) ⇒ actor - case None ⇒ - //TODO FIXME Add case for when hostname+port == remote.address.hostname+port, should return a DeadActorRef or something - val remote = application.value.reflective.RemoteModule - if (remote.isEnabled) - RemoteActorRef(application.value, remote.defaultRemoteSupport.get(), new InetSocketAddress(hostname, port), address, None) - else - throw new IllegalStateException( - "Trying to deserialize ActorRef [" + this + - "] but it's not found in the local registry and remoting is not enabled.") + def readResolve(): AnyRef = { + if (application.value eq null) throw new IllegalStateException( + "Trying to deserialize a serialized ActorRef without an AkkaApplication in scope." + + " Use akka.serialization.Serialization.application.withValue(akkaApplication) { ... }") + application.value.registry.local.actorFor(uuid) match { + case Some(actor) ⇒ actor + case None ⇒ + //TODO FIXME Add case for when hostname+port == remote.address.hostname+port, should return a DeadActorRef or something + val remote = application.value.reflective.RemoteModule + if (remote.isEnabled) + RemoteActorRef(application.value, remote.defaultRemoteSupport.get(), new InetSocketAddress(hostname, port), address, None) + else + throw new IllegalStateException( + "Trying to deserialize ActorRef [" + this + + "] but it's not found in the local registry and remoting is not enabled.") + } } } diff --git a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala index 191a442e7a..72bcf94fc3 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala @@ -56,8 +56,8 @@ trait ActorRefFactory { def createActor[T <: Actor](clazz: Class[T]): ActorRef = createActor(Props(clazz)) def createActor(factory: ⇒ Actor): ActorRef = createActor(Props(() ⇒ factory)) - - def createActor(creator: UntypedActorFactory): ActorRef = createActor(Props(() => creator.create())) + + def createActor(creator: UntypedActorFactory): ActorRef = createActor(Props(() ⇒ creator.create())) def findActor(address: String): Option[ActorRef] = provider.findActorRef(address) diff --git a/akka-http/src/main/scala/akka/http/JettyContinuation.scala b/akka-http/src/main/scala/akka/http/JettyContinuation.scala index fea864541e..d6665b00e3 100644 --- a/akka-http/src/main/scala/akka/http/JettyContinuation.scala +++ b/akka-http/src/main/scala/akka/http/JettyContinuation.scala @@ -16,7 +16,7 @@ import akka.AkkaApplication */ trait JettyContinuation extends ContinuationListener { import javax.servlet.http.HttpServletResponse - + protected def application: AkkaApplication val builder: () ⇒ tAsyncRequestContext diff --git a/akka-http/src/main/scala/akka/http/Mist.scala b/akka-http/src/main/scala/akka/http/Mist.scala index 1139575aa7..829db96286 100644 --- a/akka-http/src/main/scala/akka/http/Mist.scala +++ b/akka-http/src/main/scala/akka/http/Mist.scala @@ -47,14 +47,12 @@ object Types { def Headers(): Headers = Nil } - - /** * */ trait Mist { import javax.servlet.ServletContext - + protected def application: AkkaApplication /** @@ -124,7 +122,7 @@ trait Mist { trait RootEndpointLocator { var root: ActorRef = null - + protected def application: AkkaApplication def configureRoot(address: String) { diff --git a/akka-http/src/main/scala/akka/http/Servlet30Context.scala b/akka-http/src/main/scala/akka/http/Servlet30Context.scala index e2436c3361..8f3c191d32 100644 --- a/akka-http/src/main/scala/akka/http/Servlet30Context.scala +++ b/akka-http/src/main/scala/akka/http/Servlet30Context.scala @@ -14,7 +14,7 @@ import akka.AkkaApplication */ trait Servlet30Context extends AsyncListener { import javax.servlet.http.HttpServletResponse - + protected def application: AkkaApplication val builder: () ⇒ tAsyncRequestContext