diff --git a/akka-actor/src/main/scala/akka/util/ReflectiveAccess.scala b/akka-actor/src/main/scala/akka/util/ReflectiveAccess.scala index 23587198a9..d64704589a 100644 --- a/akka-actor/src/main/scala/akka/util/ReflectiveAccess.scala +++ b/akka-actor/src/main/scala/akka/util/ReflectiveAccess.scala @@ -151,12 +151,10 @@ object ReflectiveAccess { instance.setAccessible(true) Option(instance.get(null).asInstanceOf[T]) } catch { - case e: ClassNotFoundException => { + case e: ClassNotFoundException => None - } - case ei: ExceptionInInitializerError => { + case ei: ExceptionInInitializerError => throw ei - } } def getClassFor[T](fqn: String, classloader: ClassLoader = loader): Option[Class[T]] = try { @@ -166,26 +164,4 @@ object ReflectiveAccess { case e: Exception => None } - - def resolveMethod(bottomType: Class[_], methodName: String, methodSignature: Array[Class[_]]): java.lang.reflect.Method = { - var typeToResolve = bottomType - var targetMethod: java.lang.reflect.Method = null - var firstException: NoSuchMethodException = null - while((typeToResolve ne null) && (targetMethod eq null)) { - try { - targetMethod = typeToResolve.getDeclaredMethod(methodName, methodSignature:_*) - targetMethod.setAccessible(true) - } catch { - case e: NoSuchMethodException => - if (firstException eq null) - firstException = e - typeToResolve = typeToResolve.getSuperclass - } - } - - if((targetMethod eq null) && (firstException ne null)) - throw firstException - - targetMethod - } } diff --git a/akka-remote/src/main/scala/akka/remote/netty/NettyRemoteSupport.scala b/akka-remote/src/main/scala/akka/remote/netty/NettyRemoteSupport.scala index bc3197d4a1..635b40effa 100644 --- a/akka-remote/src/main/scala/akka/remote/netty/NettyRemoteSupport.scala +++ b/akka-remote/src/main/scala/akka/remote/netty/NettyRemoteSupport.scala @@ -924,10 +924,41 @@ class RemoteServerHandler( val typedActorInfo = actorInfo.getTypedActorInfo val typedActor = createTypedActor(actorInfo, channel) - val (argClasses, args) = MessageSerializer.deserialize(request.getMessage).asInstanceOf[Tuple2[Array[Class[_]],Array[AnyRef]]] + //FIXME: Add ownerTypeHint and parameter types to the TypedActorInfo? + val (ownerTypeHint, argClasses, args) = MessageSerializer.deserialize(request.getMessage).asInstanceOf[Tuple3[String,Array[Class[_]],Array[AnyRef]]] + + def resolveMethod(bottomType: Class[_], typeHint: String, methodName: String, methodSignature: Array[Class[_]]): java.lang.reflect.Method = { + var typeToResolve = bottomType + var targetMethod: java.lang.reflect.Method = null + var firstException: NoSuchMethodException = null + while((typeToResolve ne null) && (targetMethod eq null)) { + + if ((typeHint eq null) || typeToResolve.getName.startsWith(typeHint)) { + try { + targetMethod = typeToResolve.getDeclaredMethod(methodName, methodSignature:_*) + targetMethod.setAccessible(true) + } catch { + case e: NoSuchMethodException => + if (firstException eq null) + firstException = e + + } + } + + typeToResolve = typeToResolve.getSuperclass + } + + if((targetMethod eq null) && (firstException ne null)) + throw firstException + + targetMethod + } try { - val messageReceiver = ReflectiveAccess.resolveMethod(typedActor.getClass, typedActorInfo.getMethod, argClasses) + + println("%s(%s) = %s for %s" format(ownerTypeHint, argClasses.map(_.getName).mkString(", "), args.mkString(", "), typedActor.getClass.getName)) + + val messageReceiver = resolveMethod(typedActor.getClass, ownerTypeHint, typedActorInfo.getMethod, argClasses) if (request.getOneWay) messageReceiver.invoke(typedActor, args: _*) else { diff --git a/akka-typed-actor/src/main/scala/akka/actor/TypedActor.scala b/akka-typed-actor/src/main/scala/akka/actor/TypedActor.scala index cb82b76aca..b7daa198ac 100644 --- a/akka-typed-actor/src/main/scala/akka/actor/TypedActor.scala +++ b/akka-typed-actor/src/main/scala/akka/actor/TypedActor.scala @@ -921,10 +921,16 @@ private[akka] abstract class ActorAspect { val methodRtti = joinPoint.getRtti.asInstanceOf[MethodRtti] val isOneWay = TypedActor.isOneWay(methodRtti) - //val (message: Array[AnyRef], isEscaped) = escapeArguments(methodRtti.getParameterValues) - val message: Tuple2[Array[Class[_]],Array[AnyRef]] = { - ((methodRtti.getParameterTypes, methodRtti.getParameterValues)) - } + def extractOwnerTypeHint(s: String) = + s.indexOf("$$ProxiedByAW") match { + case -1 => s + case x => s.substring(0,x) + } + //FIXME: Add ownerTypeHint and parameter types to the TypedActorInfo? + val message: Tuple3[String, Array[Class[_]], Array[AnyRef]] = + ((extractOwnerTypeHint(methodRtti.getMethod.getDeclaringClass.getName), + methodRtti.getParameterTypes, + methodRtti.getParameterValues)) val future = Actor.remote.send[AnyRef]( message, None, None, remoteAddress.get, @@ -945,18 +951,6 @@ private[akka] abstract class ActorAspect { } } - /*private def escapeArguments(args: Array[AnyRef]): Tuple2[Array[AnyRef], Boolean] = { - var isEscaped = false - val escapedArgs = for (arg <- args) yield { - val clazz = arg.getClass - if (clazz.getName.contains(TypedActor.AW_PROXY_PREFIX)) { - isEscaped = true - TypedActor.AW_PROXY_PREFIX + clazz.getSuperclass.getName - } else arg - } - (escapedArgs, isEscaped) - }*/ - protected def initialize(joinPoint: JoinPoint) { isInitialized.switchOn { val init = AspectInitRegistry.initFor(joinPoint.getThis)