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.