diff --git a/akka-actor/src/main/scala/akka/AkkaException.scala b/akka-actor/src/main/scala/akka/AkkaException.scala index 748df1ced0..fe0bac916e 100644 --- a/akka-actor/src/main/scala/akka/AkkaException.scala +++ b/akka-actor/src/main/scala/akka/AkkaException.scala @@ -16,7 +16,7 @@ import java.net.{InetAddress, UnknownHostException} * * @author Jonas Bonér */ -class AkkaException(message: String = "") extends RuntimeException(message) with Serializable { +class AkkaException(message: String = "", cause: Throwable = null) extends RuntimeException(message, cause) with Serializable { val uuid = "%s_%s".format(AkkaException.hostname, newUuid) override lazy val toString = { diff --git a/akka-actor/src/main/scala/akka/actor/Actor.scala b/akka-actor/src/main/scala/akka/actor/Actor.scala index cf4c1bf042..104283d853 100644 --- a/akka-actor/src/main/scala/akka/actor/Actor.scala +++ b/akka-actor/src/main/scala/akka/actor/Actor.scala @@ -67,12 +67,12 @@ case class MaximumNumberOfRestartsWithinTimeRangeReached( @BeanProperty val lastExceptionCausingRestart: Throwable) extends LifeCycleMessage // Exceptions for Actors -class ActorStartException private[akka](message: String) extends AkkaException(message) -class IllegalActorStateException private[akka](message: String) extends AkkaException(message) -class ActorKilledException private[akka](message: String) extends AkkaException(message) -class ActorInitializationException private[akka](message: String) extends AkkaException(message) -class ActorTimeoutException private[akka](message: String) extends AkkaException(message) -class InvalidMessageException private[akka](message: String) extends AkkaException(message) +class ActorStartException private[akka](message: String, cause: Throwable = null) extends AkkaException(message, cause) +class IllegalActorStateException private[akka](message: String, cause: Throwable = null) extends AkkaException(message, cause) +class ActorKilledException private[akka](message: String, cause: Throwable = null) extends AkkaException(message, cause) +class ActorInitializationException private[akka](message: String, cause: Throwable = null) extends AkkaException(message, cause) +class ActorTimeoutException private[akka](message: String, cause: Throwable = null) extends AkkaException(message, cause) +class InvalidMessageException private[akka](message: String, cause: Throwable = null) extends AkkaException(message, cause) /** * This message is thrown by default when an Actors behavior doesn't match a message @@ -161,12 +161,15 @@ object Actor extends ListenerManagement { */ def actorOf(clazz: Class[_ <: Actor]): ActorRef = new LocalActorRef(() => { import ReflectiveAccess.{ createInstance, noParams, noArgs } - createInstance[Actor](clazz.asInstanceOf[Class[_]], noParams, noArgs).getOrElse( - throw new ActorInitializationException( + createInstance[Actor](clazz.asInstanceOf[Class[_]], noParams, noArgs) match { + case r: Right[Exception, Actor] => r.b + case l: Left[Exception, Actor] => throw new ActorInitializationException( "Could not instantiate Actor of " + clazz + "\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)'.", l.a) + } + }, None) /** diff --git a/akka-actor/src/main/scala/akka/actor/Supervisor.scala b/akka-actor/src/main/scala/akka/actor/Supervisor.scala index e32b515ae5..50071524dc 100644 --- a/akka-actor/src/main/scala/akka/actor/Supervisor.scala +++ b/akka-actor/src/main/scala/akka/actor/Supervisor.scala @@ -13,7 +13,7 @@ import java.util.concurrent.{CopyOnWriteArrayList, ConcurrentHashMap} import java.net.InetSocketAddress import akka.config.Supervision._ -class SupervisorException private[akka](message: String) extends AkkaException(message) +class SupervisorException private[akka](message: String, cause: Throwable = null) extends AkkaException(message, cause) /** * Factory object for creating supervisors declarative. It creates instances of the 'Supervisor' class. diff --git a/akka-actor/src/main/scala/akka/config/Config.scala b/akka-actor/src/main/scala/akka/config/Config.scala index 7d50e59cd7..1b5d8f774e 100644 --- a/akka-actor/src/main/scala/akka/config/Config.scala +++ b/akka-actor/src/main/scala/akka/config/Config.scala @@ -6,8 +6,8 @@ package akka.config import akka.AkkaException -class ConfigurationException(message: String) extends AkkaException(message) -class ModuleNotAvailableException(message: String) extends AkkaException(message) +class ConfigurationException(message: String, cause: Throwable = null) extends AkkaException(message, cause) +class ModuleNotAvailableException(message: String, cause: Throwable = null) extends AkkaException(message, cause) /** * Loads up the configuration (from the akka.conf file). diff --git a/akka-actor/src/main/scala/akka/dataflow/DataFlow.scala b/akka-actor/src/main/scala/akka/dataflow/DataFlow.scala index 446bc9652b..258bc4fff0 100644 --- a/akka-actor/src/main/scala/akka/dataflow/DataFlow.scala +++ b/akka-actor/src/main/scala/akka/dataflow/DataFlow.scala @@ -23,7 +23,7 @@ object DataFlow { object Start object Exit - class DataFlowVariableException(msg: String) extends AkkaException(msg) + class DataFlowVariableException(message: String, cause: Throwable = null) extends AkkaException(message, cause) /** * Executes the supplied thunk in another thread. diff --git a/akka-actor/src/main/scala/akka/dispatch/Dispatchers.scala b/akka-actor/src/main/scala/akka/dispatch/Dispatchers.scala index 04ff6a9504..eee5d53c51 100644 --- a/akka-actor/src/main/scala/akka/dispatch/Dispatchers.scala +++ b/akka-actor/src/main/scala/akka/dispatch/Dispatchers.scala @@ -187,14 +187,14 @@ object Dispatchers { case "GlobalExecutorBasedEventDriven" => GlobalExecutorBasedEventDrivenDispatcherConfigurator case fqn => ReflectiveAccess.getClassFor[MessageDispatcherConfigurator](fqn) match { - case Some(clazz) => - val instance = ReflectiveAccess.createInstance[MessageDispatcherConfigurator](clazz, Array[Class[_]](), Array[AnyRef]()) - if (instance.isEmpty) - throw new IllegalArgumentException("Cannot instantiate MessageDispatcherConfigurator type [%s], make sure it has a default no-args constructor" format fqn) - else - instance.get - case None => - throw new IllegalArgumentException("Unknown MessageDispatcherConfigurator type [%s]" format fqn) + case r: Right[_, Class[MessageDispatcherConfigurator]] => + ReflectiveAccess.createInstance[MessageDispatcherConfigurator](r.b, Array[Class[_]](), Array[AnyRef]()) match { + case r: Right[Exception, MessageDispatcherConfigurator] => r.b + case l: Left[Exception, MessageDispatcherConfigurator] => + throw new IllegalArgumentException("Cannot instantiate MessageDispatcherConfigurator type [%s], make sure it has a default no-args constructor" format fqn, l.a) + } + case l: Left[Exception, _] => + throw new IllegalArgumentException("Unknown MessageDispatcherConfigurator type [%s]" format fqn, l.a) } } map { _ configure cfg diff --git a/akka-actor/src/main/scala/akka/dispatch/Future.scala b/akka-actor/src/main/scala/akka/dispatch/Future.scala index ff0b6fdc57..11c124e55c 100644 --- a/akka-actor/src/main/scala/akka/dispatch/Future.scala +++ b/akka-actor/src/main/scala/akka/dispatch/Future.scala @@ -19,7 +19,7 @@ import java.util.{LinkedList => JLinkedList} import scala.collection.mutable.Stack import annotation.tailrec -class FutureTimeoutException(message: String) extends AkkaException(message) +class FutureTimeoutException(message: String, cause: Throwable = null) extends AkkaException(message, cause) object Futures { diff --git a/akka-actor/src/main/scala/akka/dispatch/MailboxHandling.scala b/akka-actor/src/main/scala/akka/dispatch/MailboxHandling.scala index cacdefe95c..388d8f10b0 100644 --- a/akka-actor/src/main/scala/akka/dispatch/MailboxHandling.scala +++ b/akka-actor/src/main/scala/akka/dispatch/MailboxHandling.scala @@ -11,7 +11,7 @@ import java.util.{Queue, List, Comparator, PriorityQueue} import java.util.concurrent._ import akka.util._ -class MessageQueueAppendFailedException(message: String) extends AkkaException(message) +class MessageQueueAppendFailedException(message: String, cause: Throwable = null) extends AkkaException(message, cause) /** * @author Jonas Bonér diff --git a/akka-actor/src/main/scala/akka/event/EventHandler.scala b/akka-actor/src/main/scala/akka/event/EventHandler.scala index 1d7d81c1b6..15dd7eaa30 100644 --- a/akka-actor/src/main/scala/akka/event/EventHandler.scala +++ b/akka-actor/src/main/scala/akka/event/EventHandler.scala @@ -220,14 +220,15 @@ object EventHandler extends ListenerManagement { } defaultListeners foreach { listenerName => try { - ReflectiveAccess.getClassFor[Actor](listenerName) map { clazz => - addListener(Actor.actorOf(clazz).start()) + ReflectiveAccess.getClassFor[Actor](listenerName) match { + case r: Right[_, Class[Actor]] => addListener(Actor.actorOf(r.b).start()) + case l: Left[Exception,_] => throw l.a } } catch { case e: Exception => throw new ConfigurationException( "Event Handler specified in config can't be loaded [" + listenerName + - "] due to [" + e.toString + "]") + "] due to [" + e.toString + "]", e) } } } diff --git a/akka-actor/src/main/scala/akka/remoteinterface/RemoteInterface.scala b/akka-actor/src/main/scala/akka/remoteinterface/RemoteInterface.scala index 7b61f224e8..695885ad9a 100644 --- a/akka-actor/src/main/scala/akka/remoteinterface/RemoteInterface.scala +++ b/akka-actor/src/main/scala/akka/remoteinterface/RemoteInterface.scala @@ -116,7 +116,7 @@ case class RemoteServerWriteFailed( class RemoteClientException private[akka] ( message: String, @BeanProperty val client: RemoteClientModule, - val remoteAddress: InetSocketAddress) extends AkkaException(message) + val remoteAddress: InetSocketAddress, cause: Throwable = null) extends AkkaException(message, cause) /** * Thrown when the remote server actor dispatching fails for some reason. @@ -189,13 +189,14 @@ abstract class RemoteSupport extends ListenerManagement with RemoteServerModule def actorOf(clazz: Class[_ <: Actor], host: String, port: Int): ActorRef = { import ReflectiveAccess.{ createInstance, noParams, noArgs } clientManagedActorOf(() => - createInstance[Actor](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)'.")), - host, port) + createInstance[Actor](clazz.asInstanceOf[Class[_]], noParams, noArgs) match { + case r: Right[_, Actor] => r.b + case l: Left[Exception, _] => 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)'.", l.a) + }, host, port) } /** @@ -217,13 +218,14 @@ abstract class RemoteSupport extends ListenerManagement with RemoteServerModule def actorOf[T <: Actor : Manifest](host: String, port: Int): ActorRef = { import ReflectiveAccess.{ createInstance, noParams, noArgs } clientManagedActorOf(() => - createInstance[Actor](manifest[T].erasure.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)'.")), - host, port) + createInstance[Actor](manifest[T].erasure.asInstanceOf[Class[_]], noParams, noArgs) match { + case r: Right[_, Actor] => r.b + case l: Left[Exception, _] => 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)'.", l.a) + }, host, port) } protected override def manageLifeCycleOfListeners = false diff --git a/akka-actor/src/main/scala/akka/util/ReflectiveAccess.scala b/akka-actor/src/main/scala/akka/util/ReflectiveAccess.scala index cda46c1a95..6164be7bef 100644 --- a/akka-actor/src/main/scala/akka/util/ReflectiveAccess.scala +++ b/akka-actor/src/main/scala/akka/util/ReflectiveAccess.scala @@ -42,12 +42,16 @@ object ReflectiveAccess { lazy val isEnabled = remoteSupportClass.isDefined def ensureEnabled = if (!isEnabled) { - val e = new ModuleNotAvailableException( - "Can't load the remoting module, make sure that akka-remote.jar is on the classpath") + val e = new ModuleNotAvailableException("Can't load the remoting module, make sure that akka-remote.jar is on the classpath") EventHandler.debug(this, e.toString) throw e } - val remoteSupportClass: Option[Class[_ <: RemoteSupport]] = getClassFor(TRANSPORT) + val remoteSupportClass = getClassFor[RemoteSupport](TRANSPORT) match { + case r: Right[_, Class[RemoteSupport]] => Some(r.b) + case l: Left[Exception,_] => + EventHandler.debug(this, l.a) + None + } protected[akka] val defaultRemoteSupport: Option[() => RemoteSupport] = remoteSupportClass map { remoteClass => @@ -55,9 +59,11 @@ object ReflectiveAccess { remoteClass, Array[Class[_]](), Array[AnyRef]() - ) getOrElse { + ) match { + case r: Right[Exception, RemoteSupport] => r.b + case l: Left[Exception, RemoteSupport] => val e = new ModuleNotAvailableException( - "Can't instantiate [%s] - make sure that akka-remote.jar is on the classpath".format(remoteClass.getName)) + "Can't instantiate [%s] - make sure that akka-remote.jar is on the classpath".format(remoteClass.getName), l.a) EventHandler.debug(this, e.toString) throw e } @@ -114,7 +120,12 @@ object ReflectiveAccess { getObjectFor("akka.cloud.cluster.Cluster$") val serializerClass: Option[Class[_]] = - getClassFor("akka.serialization.Serializer") + getClassFor("akka.serialization.Serializer") match { + case r: Right[_, Class[_]] => Some(r.b) + case l: Left[Exception,_] => + EventHandler.debug(this, l.toString) + None + } def ensureEnabled = if (!isEnabled) throw new ModuleNotAvailableException( "Feature is only available in Akka Cloud") @@ -125,17 +136,15 @@ object ReflectiveAccess { def createInstance[T](clazz: Class[_], params: Array[Class[_]], - args: Array[AnyRef]): Option[T] = try { + args: Array[AnyRef]): Either[Exception,T] = try { assert(clazz ne null) assert(params ne null) assert(args ne null) val ctor = clazz.getDeclaredConstructor(params: _*) ctor.setAccessible(true) - Some(ctor.newInstance(args: _*).asInstanceOf[T]) + Right(ctor.newInstance(args: _*).asInstanceOf[T]) } catch { - case e: Exception => - EventHandler.debug(this, e.toString) - None + case e: Exception => Left(e) } def createInstance[T](fqn: String, @@ -145,11 +154,11 @@ object ReflectiveAccess { assert(params ne null) assert(args ne null) getClassFor(fqn) match { - case Some(clazz) => - val ctor = clazz.getDeclaredConstructor(params: _*) + case r: Right[Exception, Class[T]] => + val ctor = r.b.getDeclaredConstructor(params: _*) ctor.setAccessible(true) Some(ctor.newInstance(args: _*).asInstanceOf[T]) - case None => None + case _ => None } } catch { case e: Exception => @@ -159,11 +168,11 @@ object ReflectiveAccess { def getObjectFor[T](fqn: String, classloader: ClassLoader = loader): Option[T] = try {//Obtains a reference to $MODULE$ getClassFor(fqn) match { - case Some(clazz) => - val instance = clazz.getDeclaredField("MODULE$") + case r: Right[Exception, Class[T]] => + val instance = r.b.getDeclaredField("MODULE$") instance.setAccessible(true) Option(instance.get(null).asInstanceOf[T]) - case None => None + case _ => None } } catch { case e: ExceptionInInitializerError => @@ -171,45 +180,44 @@ object ReflectiveAccess { throw e } - def getClassFor[T](fqn: String, classloader: ClassLoader = loader): Option[Class[T]] = { + def getClassFor[T](fqn: String, classloader: ClassLoader = loader): Either[Exception,Class[T]] = try { assert(fqn ne null) // First, use the specified CL val first = try { - Option(classloader.loadClass(fqn).asInstanceOf[Class[T]]) + Right(classloader.loadClass(fqn).asInstanceOf[Class[T]]) } catch { - case c: ClassNotFoundException => None + case c: ClassNotFoundException => Left(c) } - if (first.isDefined) first + if (first.isRight) first else { // Second option is to use the ContextClassLoader val second = try { - Option(Thread.currentThread.getContextClassLoader.loadClass(fqn).asInstanceOf[Class[T]]) + Right(Thread.currentThread.getContextClassLoader.loadClass(fqn).asInstanceOf[Class[T]]) } catch { - case c: ClassNotFoundException => None + case c: ClassNotFoundException => Left(c) } - if (second.isDefined) second + if (second.isRight) second else { val third = try { - // Don't try to use "loader" if we got the default "classloader" parameter - if (classloader ne loader) Option(loader.loadClass(fqn).asInstanceOf[Class[T]]) - else None + if (classloader ne loader) Right(loader.loadClass(fqn).asInstanceOf[Class[T]]) else Left(null) //Horrid } catch { - case c: ClassNotFoundException => None + case c: ClassNotFoundException => Left(c) } - if (third.isDefined) third + if (third.isRight) third else { - // Last option is Class.forName try { - Option(Class.forName(fqn).asInstanceOf[Class[T]]) + Right(Class.forName(fqn).asInstanceOf[Class[T]]) // Last option is Class.forName } catch { - case c: ClassNotFoundException => None + case c: ClassNotFoundException => Left(c) } } } } + } catch { + case e: Exception => Left(e) } } 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 7196231c2d..7caea56e88 100644 --- a/akka-remote/src/main/scala/akka/remote/netty/NettyRemoteSupport.scala +++ b/akka-remote/src/main/scala/akka/remote/netty/NettyRemoteSupport.scala @@ -41,7 +41,7 @@ import java.util.concurrent.atomic.{AtomicReference, AtomicBoolean} import java.util.concurrent._ import akka.AkkaException -class RemoteClientMessageBufferException(message: String) extends AkkaException(message) +class RemoteClientMessageBufferException(message: String, cause: Throwable = null) extends AkkaException(message, cause) object RemoteEncoder { def encode(rmp: RemoteMessageProtocol): AkkaRemoteProtocol = { diff --git a/akka-testkit/src/main/scala/akka/testkit/TestActorRef.scala b/akka-testkit/src/main/scala/akka/testkit/TestActorRef.scala index a31582ac3a..53ceed69eb 100644 --- a/akka-testkit/src/main/scala/akka/testkit/TestActorRef.scala +++ b/akka-testkit/src/main/scala/akka/testkit/TestActorRef.scala @@ -72,12 +72,14 @@ object TestActorRef { def apply[T <: Actor : Manifest] : TestActorRef[T] = new TestActorRef[T] ({ () => import ReflectiveAccess.{ createInstance, noParams, noArgs } - createInstance[T](manifest[T].erasure, noParams, noArgs).getOrElse( - throw new ActorInitializationException( + createInstance[T](manifest[T].erasure, noParams, noArgs) match { + case r: Right[_, T] => r.b + case l: Left[Exception, _] => 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)'.", l.a) + } }) } diff --git a/akka-typed-actor/src/main/scala/akka/transactor/Coordination.scala b/akka-typed-actor/src/main/scala/akka/transactor/Coordination.scala index 33a74fea79..1f72176eed 100644 --- a/akka-typed-actor/src/main/scala/akka/transactor/Coordination.scala +++ b/akka-typed-actor/src/main/scala/akka/transactor/Coordination.scala @@ -9,7 +9,7 @@ import akka.stm.Atomic import scala.util.DynamicVariable -class CoordinateException private[akka](message: String) extends AkkaException(message) +class CoordinateException private[akka](message: String, cause: Throwable = null) extends AkkaException(message, cause) /** * Coordinating transactions between typed actors.