diff --git a/akka-actor/src/main/scala/akka/actor/Actor.scala b/akka-actor/src/main/scala/akka/actor/Actor.scala index 1b616c55e8..d02f37cf7b 100644 --- a/akka-actor/src/main/scala/akka/actor/Actor.scala +++ b/akka-actor/src/main/scala/akka/actor/Actor.scala @@ -300,6 +300,11 @@ object Actor { def apply(x: Any) = throw new UnsupportedOperationException("Empty behavior apply()") } + /** + * Default placeholder (null) used for "!" to indicate that there is no sender of the message, + * that will be translated to the receiving system's deadLetters. + */ + final val noSender: ActorRef = null } /** diff --git a/akka-actor/src/main/scala/akka/actor/ActorRef.scala b/akka-actor/src/main/scala/akka/actor/ActorRef.scala index 2cb2f984f2..d7d971837c 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorRef.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRef.scala @@ -153,7 +153,7 @@ trait ScalaActorRef { ref: ActorRef ⇒ * *
*/ - def !(message: Any)(implicit sender: ActorRef = null): Unit + def !(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit } @@ -341,7 +341,7 @@ private[akka] class LocalActorRef private[akka] ( override def sendSystemMessage(message: SystemMessage): Unit = actorCell.sendSystemMessage(message) - override def !(message: Any)(implicit sender: ActorRef = null): Unit = actorCell.tell(message, sender) + override def !(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit = actorCell.tell(message, sender) override def restart(cause: Throwable): Unit = actorCell.restart(cause) @@ -395,7 +395,7 @@ private[akka] trait MinimalActorRef extends InternalActorRef with LocalRef { override def stop(): Unit = () override def isTerminated = false - override def !(message: Any)(implicit sender: ActorRef = null): Unit = () + override def !(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit = () override def sendSystemMessage(message: SystemMessage): Unit = () override def restart(cause: Throwable): Unit = () @@ -435,7 +435,7 @@ private[akka] class EmptyLocalActorRef(override val provider: ActorRefProvider, override def sendSystemMessage(message: SystemMessage): Unit = specialHandle(message) - override def !(message: Any)(implicit sender: ActorRef = null): Unit = message match { + override def !(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit = message match { case d: DeadLetter ⇒ specialHandle(d.message) // do NOT form endless loops, since deadLetters will resend! case _ ⇒ if (!specialHandle(message)) eventStream.publish(DeadLetter(message, sender, this)) } diff --git a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala index d60a46d497..f1a4a0d141 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorRefProvider.scala @@ -375,7 +375,7 @@ class LocalActorRefProvider( override def stop(): Unit = stopped switchOn { terminationPromise.complete(causeOfTermination.map(Failure(_)).getOrElse(Success(()))) } override def isTerminated: Boolean = stopped.isOn - override def !(message: Any)(implicit sender: ActorRef = null): Unit = stopped.ifOff(message match { + override def !(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit = stopped.ifOff(message match { case Failed(ex, _) if sender ne null ⇒ causeOfTermination = Some(ex); sender.asInstanceOf[InternalActorRef].stop() case NullMessage ⇒ // do nothing case _ ⇒ log.error(this + " received unexpected message [" + message + "]") diff --git a/akka-actor/src/main/scala/akka/actor/ActorSelection.scala b/akka-actor/src/main/scala/akka/actor/ActorSelection.scala index 0740d8724e..2f4fd4219b 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorSelection.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorSelection.scala @@ -70,5 +70,5 @@ object ActorSelection { trait ScalaActorSelection { this: ActorSelection ⇒ - def !(msg: Any)(implicit sender: ActorRef = null) = tell(msg, sender) + def !(msg: Any)(implicit sender: ActorRef = Actor.noSender) = tell(msg, sender) } \ No newline at end of file diff --git a/akka-actor/src/main/scala/akka/actor/RepointableActorRef.scala b/akka-actor/src/main/scala/akka/actor/RepointableActorRef.scala index 7bbc5517d8..142cdc4dc4 100644 --- a/akka-actor/src/main/scala/akka/actor/RepointableActorRef.scala +++ b/akka-actor/src/main/scala/akka/actor/RepointableActorRef.scala @@ -112,7 +112,7 @@ private[akka] class RepointableActorRef( } } else this - def !(message: Any)(implicit sender: ActorRef = null) = underlying.tell(message, sender) + def !(message: Any)(implicit sender: ActorRef = Actor.noSender) = underlying.tell(message, sender) def sendSystemMessage(message: SystemMessage) = underlying.sendSystemMessage(message) diff --git a/akka-actor/src/main/scala/akka/event/Logging.scala b/akka-actor/src/main/scala/akka/event/Logging.scala index 48d7c44d5d..e6003f5279 100644 --- a/akka-actor/src/main/scala/akka/event/Logging.scala +++ b/akka-actor/src/main/scala/akka/event/Logging.scala @@ -708,7 +708,7 @@ object Logging { val path: ActorPath = new RootActorPath(Address("akka", "all-systems"), "/StandardOutLogger") def provider: ActorRefProvider = throw new UnsupportedOperationException("StandardOutLogger does not provide") override val toString = "StandardOutLogger" - override def !(message: Any)(implicit sender: ActorRef = null): Unit = print(message) + override def !(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit = print(message) } val StandardOutLogger = new StandardOutLogger diff --git a/akka-actor/src/main/scala/akka/pattern/AskSupport.scala b/akka-actor/src/main/scala/akka/pattern/AskSupport.scala index 704ce43d8d..43e899f81f 100644 --- a/akka-actor/src/main/scala/akka/pattern/AskSupport.scala +++ b/akka-actor/src/main/scala/akka/pattern/AskSupport.scala @@ -247,7 +247,7 @@ private[akka] final class PromiseActorRef private (val provider: ActorRefProvide case Registering ⇒ path // spin until registration is completed } - override def !(message: Any)(implicit sender: ActorRef = null): Unit = state match { + override def !(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit = state match { case Stopped | _: StoppedWithPath ⇒ provider.deadLetters ! message case _ ⇒ if (!(result.tryComplete( message match { diff --git a/akka-actor/src/main/scala/akka/pattern/PipeToSupport.scala b/akka-actor/src/main/scala/akka/pattern/PipeToSupport.scala index 5563a908de..a766954e54 100644 --- a/akka-actor/src/main/scala/akka/pattern/PipeToSupport.scala +++ b/akka-actor/src/main/scala/akka/pattern/PipeToSupport.scala @@ -7,12 +7,12 @@ import language.implicitConversions import scala.concurrent.{ Future, ExecutionContext } import scala.util.{ Failure, Success } -import akka.actor.{ Status, ActorRef } +import akka.actor.{ Status, ActorRef, Actor } trait PipeToSupport { final class PipeableFuture[T](val future: Future[T])(implicit executionContext: ExecutionContext) { - def pipeTo(recipient: ActorRef)(implicit sender: ActorRef = null): Future[T] = { + def pipeTo(recipient: ActorRef)(implicit sender: ActorRef = Actor.noSender): Future[T] = { future onComplete { case Success(r) ⇒ recipient ! r case Failure(f) ⇒ recipient ! Status.Failure(f) diff --git a/akka-actor/src/main/scala/akka/routing/Listeners.scala b/akka-actor/src/main/scala/akka/routing/Listeners.scala index 7cc48b05f8..346f994a2f 100644 --- a/akka-actor/src/main/scala/akka/routing/Listeners.scala +++ b/akka-actor/src/main/scala/akka/routing/Listeners.scala @@ -45,7 +45,7 @@ trait Listeners { self: Actor ⇒ * @param msg * @param sender */ - protected def gossip(msg: Any)(implicit sender: ActorRef = null): Unit = { + protected def gossip(msg: Any)(implicit sender: ActorRef = Actor.noSender): Unit = { val i = listeners.iterator while (i.hasNext) i.next ! msg } diff --git a/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala b/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala index 50531bfa91..4e1921a960 100644 --- a/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala +++ b/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala @@ -235,7 +235,7 @@ private[akka] class RemoteActorRef private[akka] ( provider.deadLetters ! message } - override def !(message: Any)(implicit sender: ActorRef = null): Unit = + override def !(message: Any)(implicit sender: ActorRef = Actor.noSender): Unit = try remote.send(message, Option(sender), this) catch { case e @ (_: InterruptedException | NonFatal(_)) ⇒ diff --git a/akka-remote/src/main/scala/akka/remote/RemoteDaemon.scala b/akka-remote/src/main/scala/akka/remote/RemoteDaemon.scala index ecfd544dcb..f6e000737a 100644 --- a/akka-remote/src/main/scala/akka/remote/RemoteDaemon.scala +++ b/akka-remote/src/main/scala/akka/remote/RemoteDaemon.scala @@ -63,7 +63,7 @@ private[akka] class RemoteSystemDaemon( } } - override def !(msg: Any)(implicit sender: ActorRef = null): Unit = msg match { + override def !(msg: Any)(implicit sender: ActorRef = Actor.noSender): Unit = msg match { case message: DaemonMsg ⇒ log.debug("Received command [{}] to RemoteSystemDaemon on [{}]", message, path.address) message match {