From 456fd074d4e61aa3b08052f91e4d62174954cb9c Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Tue, 7 Sep 2010 11:02:40 +0200 Subject: [PATCH] Removing boilerplate in reflective access --- .../src/main/scala/actor/ActorRef.scala | 14 ++-- .../main/scala/util/ReflectiveAccess.scala | 79 +++++++++---------- 2 files changed, 44 insertions(+), 49 deletions(-) diff --git a/akka-actor/src/main/scala/actor/ActorRef.scala b/akka-actor/src/main/scala/actor/ActorRef.scala index b250e16ff3..78c37176f8 100644 --- a/akka-actor/src/main/scala/actor/ActorRef.scala +++ b/akka-actor/src/main/scala/actor/ActorRef.scala @@ -1153,17 +1153,13 @@ class LocalActorRef private[akka]( isInInitialization = true val actor = actorFactory match { case Left(Some(clazz)) => - try { - val ctor = clazz.getConstructor() - ctor.setAccessible(true) - ctor.newInstance() - } catch { - case e: InstantiationException => throw new ActorInitializationException( - "Could not instantiate Actor due to:\n" + e + + import ReflectiveAccess.{createInstance,noParams,noArgs} + createInstance(clazz.asInstanceOf[Class[_]],noParams,noArgs). + getOrElse(throw new ActorInitializationException( + "Could not instantiate Actor" + "\nMake sure Actor is NOT defined inside a class/trait," + "\nif so put it outside the class/trait, f.e. in a companion object," + - "\nOR try to change: 'actorOf[MyActor]' to 'actorOf(new MyActor)'.") - } + "\nOR try to change: 'actorOf[MyActor]' to 'actorOf(new MyActor)'.")) case Right(Some(factory)) => factory() case _ => diff --git a/akka-actor/src/main/scala/util/ReflectiveAccess.scala b/akka-actor/src/main/scala/util/ReflectiveAccess.scala index 4582304188..2da11c4e97 100644 --- a/akka-actor/src/main/scala/util/ReflectiveAccess.scala +++ b/akka-actor/src/main/scala/util/ReflectiveAccess.scala @@ -62,14 +62,8 @@ object ReflectiveAccess { def ensureRemotingEnabled = if (!isRemotingEnabled) throw new ModuleNotAvailableException( "Can't load the remoting module, make sure that akka-remote.jar is on the classpath") - val remoteClientObjectInstance: Option[RemoteClientObject] = { - try { - val clazz = loader.loadClass("se.scalablesolutions.akka.remote.RemoteClient$") - val ctor = clazz.getDeclaredConstructor(Array[Class[_]](): _*) - ctor.setAccessible(true) - Some(ctor.newInstance(Array[AnyRef](): _*).asInstanceOf[RemoteClientObject]) - } catch { case e: Exception => None } - } + val remoteClientObjectInstance: Option[RemoteClientObject] = + createInstance("se.scalablesolutions.akka.remote.RemoteClient$",noParams,noArgs) def register(address: InetSocketAddress, uuid: String) = { ensureRemotingEnabled @@ -126,23 +120,11 @@ object ReflectiveAccess { def unregister(actorRef: ActorRef): Unit } - val remoteServerObjectInstance: Option[RemoteServerObject] = { - try { - val clazz = loader.loadClass("se.scalablesolutions.akka.remote.RemoteServer$") - val ctor = clazz.getDeclaredConstructor(Array[Class[_]](): _*) - ctor.setAccessible(true) - Some(ctor.newInstance(Array[AnyRef](): _*).asInstanceOf[RemoteServerObject]) - } catch { case e: Exception => None } - } + val remoteServerObjectInstance: Option[RemoteServerObject] = + createInstance("se.scalablesolutions.akka.remote.RemoteServer$",noParams,noArgs) - val remoteNodeObjectInstance: Option[RemoteNodeObject] = { - try { - val clazz = loader.loadClass("se.scalablesolutions.akka.remote.RemoteNode$") - val ctor = clazz.getDeclaredConstructor(Array[Class[_]](): _*) - ctor.setAccessible(true) - Some(ctor.newInstance(Array[AnyRef](): _*).asInstanceOf[RemoteNodeObject]) - } catch { case e: Exception => None } - } + val remoteNodeObjectInstance: Option[RemoteNodeObject] = + createInstance("se.scalablesolutions.akka.remote.RemoteNode$",noParams,noArgs) def registerActor(address: InetSocketAddress, uuid: String, actorRef: ActorRef) = { ensureRemotingEnabled @@ -177,14 +159,8 @@ object ReflectiveAccess { def ensureTypedActorEnabled = if (!isTypedActorEnabled) throw new ModuleNotAvailableException( "Can't load the typed actor module, make sure that akka-typed-actor.jar is on the classpath") - val typedActorObjectInstance: Option[TypedActorObject] = { - try { - val clazz = loader.loadClass("se.scalablesolutions.akka.actor.TypedActor$") - val ctor = clazz.getDeclaredConstructor(Array[Class[_]](): _*) - ctor.setAccessible(true) - Some(ctor.newInstance(Array[AnyRef](): _*).asInstanceOf[TypedActorObject]) - } catch { case e: Exception => None } - } + val typedActorObjectInstance: Option[TypedActorObject] = + createInstance("se.scalablesolutions.akka.actor.TypedActor$",noParams,noArgs) def resolveFutureIfMessageIsJoinPoint(message: Any, future: Future[_]): Boolean = { ensureTypedActorEnabled @@ -212,18 +188,41 @@ object ReflectiveAccess { def ensureJtaEnabled = if (!isJtaEnabled) throw new ModuleNotAvailableException( "Can't load the typed actor module, make sure that akka-jta.jar is on the classpath") - val transactionContainerObjectInstance: Option[TransactionContainerObject] = { - try { - val clazz = loader.loadClass("se.scalablesolutions.akka.actor.TransactionContainer$") - val ctor = clazz.getDeclaredConstructor(Array[Class[_]](): _*) - ctor.setAccessible(true) - Some(ctor.newInstance(Array[AnyRef](): _*).asInstanceOf[TransactionContainerObject]) - } catch { case e: Exception => None } - } + val transactionContainerObjectInstance: Option[TransactionContainerObject] = + createInstance("se.scalablesolutions.akka.actor.TransactionContainer$",noParams,noArgs) def createTransactionContainer: TransactionContainer = { ensureJtaEnabled transactionContainerObjectInstance.get.apply.asInstanceOf[TransactionContainer] } } + + val noParams = Array[Class[_]]() + val noArgs = Array[AnyRef]() + + def createInstance[T](clazz: Class[_], + params: Array[Class[_]], + args: Array[AnyRef]): Option[T] = try { + val ctor = clazz.getDeclaredConstructor(params: _*) + ctor.setAccessible(true) + Some(ctor.newInstance(args: _*).asInstanceOf[T]) + } catch { + case e: Exception => + Logger("createInstance").error(e, "Couldn't load [%s(%s) => %s(%s)]",clazz.getName,params.mkString(", "),clazz.getName,args.mkString(", ")) + None + } + + def createInstance[T](fqn: String, + params: Array[Class[_]], + args: Array[AnyRef], + classloader: ClassLoader = loader): Option[T] = try { + val clazz = classloader.loadClass(fqn) + val ctor = clazz.getDeclaredConstructor(params: _*) + ctor.setAccessible(true) + Some(ctor.newInstance(args: _*).asInstanceOf[T]) + } catch { + case e: Exception => + Logger("createInstance").error(e, "Couldn't load [%s(%s) => %s(%s)]",fqn,params.mkString(", "),fqn,args.mkString(", ")) + None + } }