diff --git a/akka-actor/src/main/scala/akka/actor/ActorCell.scala b/akka-actor/src/main/scala/akka/actor/ActorCell.scala index 21b6fc4d82..ba2c1922cb 100644 --- a/akka-actor/src/main/scala/akka/actor/ActorCell.scala +++ b/akka-actor/src/main/scala/akka/actor/ActorCell.scala @@ -17,6 +17,7 @@ import scala.concurrent.duration.Duration import java.util.concurrent.ThreadLocalRandom import scala.util.control.NonFatal import akka.dispatch.MessageDispatcher +import akka.util.Reflect /** * The actor context - the view of the actor cell from the actor. @@ -624,28 +625,9 @@ private[akka] class ActorCell( case _ ⇒ } - @tailrec private final def lookupAndSetField(clazz: Class[_], instance: AnyRef, name: String, value: Any): Boolean = { - @tailrec def clearFirst(fields: Array[java.lang.reflect.Field], idx: Int): Boolean = - if (idx < fields.length) { - val field = fields(idx) - if (field.getName == name) { - field.setAccessible(true) - field.set(instance, value) - true - } else clearFirst(fields, idx + 1) - } else false - - clearFirst(clazz.getDeclaredFields, 0) || { - clazz.getSuperclass match { - case null ⇒ false // clazz == classOf[AnyRef] - case sc ⇒ lookupAndSetField(sc, instance, name, value) - } - } - } - final protected def clearActorCellFields(cell: ActorCell): Unit = { cell.unstashAll() - if (!lookupAndSetField(classOf[ActorCell], cell, "props", ActorCell.terminatedProps)) + if (!Reflect.lookupAndSetField(classOf[ActorCell], cell, "props", ActorCell.terminatedProps)) throw new IllegalArgumentException("ActorCell has no props field") } @@ -657,8 +639,8 @@ private[akka] class ActorCell( final protected def setActorFields(actorInstance: Actor, context: ActorContext, self: ActorRef): Unit = if (actorInstance ne null) { - if (!lookupAndSetField(actorInstance.getClass, actorInstance, "context", context) - || !lookupAndSetField(actorInstance.getClass, actorInstance, "self", self)) + if (!Reflect.lookupAndSetField(actorInstance.getClass, actorInstance, "context", context) + || !Reflect.lookupAndSetField(actorInstance.getClass, actorInstance, "self", self)) throw new IllegalActorStateException(actorInstance.getClass + " is not an Actor since it have not mixed in the 'Actor' trait") } diff --git a/akka-actor/src/main/scala/akka/util/Reflect.scala b/akka-actor/src/main/scala/akka/util/Reflect.scala index b7f641f976..e375e50376 100644 --- a/akka-actor/src/main/scala/akka/util/Reflect.scala +++ b/akka-actor/src/main/scala/akka/util/Reflect.scala @@ -131,4 +131,27 @@ private[akka] object Reflect { } rec(root) } + + /** + * INTERNAL API + * Set a val inside a class. + */ + @tailrec protected[akka] final def lookupAndSetField(clazz: Class[_], instance: AnyRef, name: String, value: Any): Boolean = { + @tailrec def clearFirst(fields: Array[java.lang.reflect.Field], idx: Int): Boolean = + if (idx < fields.length) { + val field = fields(idx) + if (field.getName == name) { + field.setAccessible(true) + field.set(instance, value) + true + } else clearFirst(fields, idx + 1) + } else false + + clearFirst(clazz.getDeclaredFields, 0) || { + clazz.getSuperclass match { + case null ⇒ false // clazz == classOf[AnyRef] + case sc ⇒ lookupAndSetField(sc, instance, name, value) + } + } + } }