From 1b1720d65a47fce3876c31ec4b4838f0c4bebed4 Mon Sep 17 00:00:00 2001 From: Peter Veentjer Date: Mon, 25 Jul 2011 12:47:43 +0300 Subject: [PATCH] ticket #1048 --- .../test/scala/akka/AkkaExceptionSpec.scala | 28 ++++++++++++++++++ .../src/main/scala/akka/AkkaException.scala | 2 ++ .../src/main/scala/akka/actor/Actor.scala | 29 +++++++++++++++---- .../src/main/scala/akka/actor/Scheduler.scala | 1 - .../main/scala/akka/actor/Supervisor.scala | 5 ++-- .../scala/akka/cluster/ClusterInterface.scala | 6 +--- .../src/main/scala/akka/config/Config.scala | 9 ++++-- .../scala/akka/cluster/TransactionLog.scala | 5 ++-- .../scala/akka/cluster/storage/Storage.scala | 16 +++++++--- .../remote/netty/NettyRemoteSupport.scala | 4 ++- .../actor/mailbox/BeanstalkBasedMailbox.scala | 2 +- .../scala/akka/transactor/Coordinated.scala | 4 ++- 12 files changed, 85 insertions(+), 26 deletions(-) create mode 100644 akka-actor-tests/src/test/scala/akka/AkkaExceptionSpec.scala diff --git a/akka-actor-tests/src/test/scala/akka/AkkaExceptionSpec.scala b/akka-actor-tests/src/test/scala/akka/AkkaExceptionSpec.scala new file mode 100644 index 0000000000..ac0b2b75cf --- /dev/null +++ b/akka-actor-tests/src/test/scala/akka/AkkaExceptionSpec.scala @@ -0,0 +1,28 @@ +package akka; + +import akka.actor._ +import org.scalatest.matchers.MustMatchers +import org.scalatest.WordSpec; + +/** + * A spec that verified that the AkkaException has at least a single argument constructor of type String. + * + * This is required to make Akka Exceptions be friends with serialization/deserialization. + */ +class AkkaExceptionSpec extends WordSpec with MustMatchers { + + "AkkaException" must { + "have a AkkaException(String msg) constructor to be serialization friendly" in { + //if the call to this method completes, we know what there is at least a single constructor which has + //the expected argument type. + verify(classOf[AkkaException]) + + //lets also try it for the exception that triggered this bug to be discovered. + verify(classOf[ActorKilledException]) + } + } + + def verify(clazz:java.lang.Class[_]):Unit = { + clazz.getConstructor(Array(classOf[String]): _*) + } +} diff --git a/akka-actor/src/main/scala/akka/AkkaException.scala b/akka-actor/src/main/scala/akka/AkkaException.scala index f87453db10..24831ff589 100644 --- a/akka-actor/src/main/scala/akka/AkkaException.scala +++ b/akka-actor/src/main/scala/akka/AkkaException.scala @@ -26,6 +26,8 @@ class AkkaException(message: String = "", cause: Throwable = null) extends Runti lazy val toLongString = "%s: %s\n[%s]\n%s".format(getClass.getName, message, uuid, stackTraceToString) + def this(msg:String) = this(msg, null); + def stackTraceToString = { val trace = getStackTrace val sb = new StringBuffer diff --git a/akka-actor/src/main/scala/akka/actor/Actor.scala b/akka-actor/src/main/scala/akka/actor/Actor.scala index b981c954ce..d988bc1819 100644 --- a/akka-actor/src/main/scala/akka/actor/Actor.scala +++ b/akka-actor/src/main/scala/akka/actor/Actor.scala @@ -80,12 +80,29 @@ case class MaximumNumberOfRestartsWithinTimeRangeReached( @BeanProperty lastExceptionCausingRestart: Throwable) extends LifeCycleMessage // Exceptions for Actors -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) +class ActorStartException private[akka] (message: String, cause: Throwable = null) extends AkkaException(message, cause){ + def this(msg:String) = this(msg, null); +} + +class IllegalActorStateException private[akka] (message: String, cause: Throwable = null) extends AkkaException(message, cause) { + def this(msg:String) = this(msg, null); +} + +class ActorKilledException private[akka] (message: String, cause: Throwable) extends AkkaException(message, cause){ + def this(msg: String) = this(msg, null); +} + +class ActorInitializationException private[akka] (message: String, cause: Throwable = null) extends AkkaException(message, cause) { + def this(msg:String) = this(msg, null); +} + +class ActorTimeoutException private[akka] (message: String, cause: Throwable = null) extends AkkaException(message, cause) { + def this(msg:String) = this(msg, null); +} + +class InvalidMessageException private[akka] (message: String, cause: Throwable = null) extends AkkaException(message, cause) { + def this(msg:String) = this(msg, null); +} /** * This message is thrown by default when an Actors behavior doesn't match a message diff --git a/akka-actor/src/main/scala/akka/actor/Scheduler.scala b/akka-actor/src/main/scala/akka/actor/Scheduler.scala index efbec15239..9c93e2dbdd 100644 --- a/akka-actor/src/main/scala/akka/actor/Scheduler.scala +++ b/akka-actor/src/main/scala/akka/actor/Scheduler.scala @@ -22,7 +22,6 @@ import java.util.concurrent._ import java.lang.RuntimeException object Scheduler { - import Actor._ case class SchedulerException(msg: String, e: Throwable) extends AkkaException(msg, e) diff --git a/akka-actor/src/main/scala/akka/actor/Supervisor.scala b/akka-actor/src/main/scala/akka/actor/Supervisor.scala index 5063ca994a..95532e8fb7 100644 --- a/akka-actor/src/main/scala/akka/actor/Supervisor.scala +++ b/akka-actor/src/main/scala/akka/actor/Supervisor.scala @@ -10,10 +10,11 @@ import ReflectiveAccess._ import Actor._ import java.util.concurrent.{ CopyOnWriteArrayList, ConcurrentHashMap } -import java.net.InetSocketAddress import akka.config.Supervision._ -class SupervisorException private[akka] (message: String, cause: Throwable = null) extends AkkaException(message, cause) +class SupervisorException private[akka] (message: String, cause: Throwable = null) extends AkkaException(message, cause) { + def this(msg:String) = this(msg, null); +} /** * Factory object for creating supervisors declarative. It creates instances of the 'Supervisor' class. diff --git a/akka-actor/src/main/scala/akka/cluster/ClusterInterface.scala b/akka-actor/src/main/scala/akka/cluster/ClusterInterface.scala index 690a69841f..f59d2ff4ab 100644 --- a/akka-actor/src/main/scala/akka/cluster/ClusterInterface.scala +++ b/akka-actor/src/main/scala/akka/cluster/ClusterInterface.scala @@ -10,18 +10,14 @@ import akka.actor._ import DeploymentConfig._ import akka.dispatch.Future import akka.config.Config -import akka.util._ import akka.routing.RouterType import akka.AkkaException import com.eaio.uuid.UUID import java.net.InetSocketAddress -import java.util.concurrent.atomic.{ AtomicBoolean, AtomicInteger } -import java.util.concurrent.{ ConcurrentSkipListSet, ConcurrentHashMap } +import java.util.concurrent.{ ConcurrentSkipListSet} -import scala.collection.mutable.ConcurrentMap -import scala.collection.JavaConversions._ class ClusterException(message: String) extends AkkaException(message) diff --git a/akka-actor/src/main/scala/akka/config/Config.scala b/akka-actor/src/main/scala/akka/config/Config.scala index 0c1505ae21..40f84a30d2 100644 --- a/akka-actor/src/main/scala/akka/config/Config.scala +++ b/akka-actor/src/main/scala/akka/config/Config.scala @@ -10,8 +10,13 @@ import java.net.InetAddress import com.eaio.uuid.UUID -class ConfigurationException(message: String, cause: Throwable = null) extends AkkaException(message, cause) -class ModuleNotAvailableException(message: String, cause: Throwable = null) extends AkkaException(message, cause) +class ConfigurationException(message: String, cause: Throwable = null) extends AkkaException(message, cause) { + def this(msg:String) = this(msg, null); +} + +class ModuleNotAvailableException(message: String, cause: Throwable = null) extends AkkaException(message, cause) { + def this(msg:String) = this(msg, null); +} /** * Loads up the configuration (from the akka.conf file). diff --git a/akka-cluster/src/main/scala/akka/cluster/TransactionLog.scala b/akka-cluster/src/main/scala/akka/cluster/TransactionLog.scala index ae98e6848e..2261829934 100644 --- a/akka-cluster/src/main/scala/akka/cluster/TransactionLog.scala +++ b/akka-cluster/src/main/scala/akka/cluster/TransactionLog.scala @@ -14,17 +14,16 @@ import akka.config._ import Config._ import akka.util._ import akka.actor._ -import DeploymentConfig.{ ReplicationScheme, ReplicationStrategy, Transient, WriteThrough, WriteBehind } +import DeploymentConfig.{ ReplicationScheme} import akka.event.EventHandler import akka.dispatch.{ DefaultPromise, Promise, MessageInvocation } import akka.remote.MessageSerializer import akka.cluster.zookeeper._ -import akka.serialization.{ Serializer, Serialization, Compression } +import akka.serialization.Compression import Compression.LZF import akka.serialization.ActorSerialization._ import java.util.Enumeration -import java.util.concurrent.atomic.AtomicLong // FIXME allow user to choose dynamically between 'async' and 'sync' tx logging (asyncAddEntry(byte[] data, AddCallback cb, Object ctx)) // FIXME clean up old entries in log after doing a snapshot diff --git a/akka-cluster/src/main/scala/akka/cluster/storage/Storage.scala b/akka-cluster/src/main/scala/akka/cluster/storage/Storage.scala index ef7b1a1aa4..0129c39eb0 100755 --- a/akka-cluster/src/main/scala/akka/cluster/storage/Storage.scala +++ b/akka-cluster/src/main/scala/akka/cluster/storage/Storage.scala @@ -118,23 +118,31 @@ class VersionedData(val data: Array[Byte], val version: Long) {} /** * An AkkaException thrown by the Storage module. */ -class StorageException(msg: String = null, cause: java.lang.Throwable = null) extends AkkaException(msg, cause) +class StorageException(msg: String = null, cause: java.lang.Throwable = null) extends AkkaException(msg, cause){ + def this(msg:String) = this(msg, null); +} /** * * * A StorageException thrown when an operation is done on a non existing node. */ -class MissingDataException(msg: String = null, cause: java.lang.Throwable = null) extends StorageException(msg, cause) +class MissingDataException(msg: String = null, cause: java.lang.Throwable = null) extends StorageException(msg, cause) { + def this(msg:String) = this(msg, null); +} /** * A StorageException thrown when an operation is done on an existing node, but no node was expected. */ -class DataExistsException(msg: String = null, cause: java.lang.Throwable = null) extends StorageException(msg, cause) +class DataExistsException(msg: String = null, cause: java.lang.Throwable = null) extends StorageException(msg, cause){ + def this(msg:String) = this(msg, null); +} /** * A StorageException thrown when an operation causes an optimistic locking failure. */ -class BadVersionException(msg: String = null, cause: java.lang.Throwable = null) extends StorageException(msg, cause) +class BadVersionException(msg: String = null, cause: java.lang.Throwable = null) extends StorageException(msg, cause) { + def this(msg:String) = this(msg, null); +} /** * A Storage implementation based on ZooKeeper. diff --git a/akka-cluster/src/main/scala/akka/remote/netty/NettyRemoteSupport.scala b/akka-cluster/src/main/scala/akka/remote/netty/NettyRemoteSupport.scala index 863e2b4917..b676e9f254 100644 --- a/akka-cluster/src/main/scala/akka/remote/netty/NettyRemoteSupport.scala +++ b/akka-cluster/src/main/scala/akka/remote/netty/NettyRemoteSupport.scala @@ -47,7 +47,9 @@ import java.util.concurrent.atomic.{AtomicReference, AtomicBoolean} import java.util.concurrent._ import akka.AkkaException -class RemoteClientMessageBufferException(message: String, cause: Throwable = null) extends AkkaException(message, cause) +class RemoteClientMessageBufferException(message: String, cause: Throwable = null) extends AkkaException(message, cause){ + def this(msg:String) = this(msg, null); +} object RemoteEncoder { def encode(rmp: RemoteMessageProtocol): AkkaRemoteProtocol = { diff --git a/akka-durable-mailboxes/akka-beanstalk-mailbox/src/main/scala/akka/actor/mailbox/BeanstalkBasedMailbox.scala b/akka-durable-mailboxes/akka-beanstalk-mailbox/src/main/scala/akka/actor/mailbox/BeanstalkBasedMailbox.scala index 35ec40edee..8138d04b14 100644 --- a/akka-durable-mailboxes/akka-beanstalk-mailbox/src/main/scala/akka/actor/mailbox/BeanstalkBasedMailbox.scala +++ b/akka-durable-mailboxes/akka-beanstalk-mailbox/src/main/scala/akka/actor/mailbox/BeanstalkBasedMailbox.scala @@ -15,7 +15,7 @@ import akka.event.EventHandler import com.surftools.BeanstalkClient._ import com.surftools.BeanstalkClientImpl._ -class BeanstalkBasedMailboxException(message: String) extends AkkaException(message) +class BeanstalkBasedMailboxException(message: String) extends AkkaException(message) {} /** * @author Jonas Bonér diff --git a/akka-stm/src/main/scala/akka/transactor/Coordinated.scala b/akka-stm/src/main/scala/akka/transactor/Coordinated.scala index a43cf39786..bd50926d72 100644 --- a/akka-stm/src/main/scala/akka/transactor/Coordinated.scala +++ b/akka-stm/src/main/scala/akka/transactor/Coordinated.scala @@ -17,7 +17,9 @@ import org.multiverse.api.exceptions.ControlFlowError /** * Akka-specific exception for coordinated transactions. */ -class CoordinatedTransactionException(message: String, cause: Throwable = null) extends AkkaException(message, cause) +class CoordinatedTransactionException(message: String, cause: Throwable = null) extends AkkaException(message, cause){ + def this(msg:String) = this(msg, null); +} /** * Coordinated transactions across actors.