From e8581123da0a2eb6bb4f230c52f0dde13a6f30f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bon=C3=A9r?= Date: Tue, 29 Jun 2010 15:19:09 +0200 Subject: [PATCH] Fixed bug in fault handling of TEMPORARY Actors + ported all Active Object Java tests to Scala (using Java POJOs) --- .../akka/api/InMemStateful.java | 1 + .../akka/api/InMemStatefulNested.java | 1 + akka-core/src/main/scala/actor/ActorRef.scala | 69 ++++++++++-------- .../src/main/scala/remote/RemoteServer.scala | 4 +- .../src/main/scala/stm/Transaction.scala | 30 +------- ...MemFailer.java => ActiveObjectFailer.java} | 2 +- .../se/scalablesolutions/akka/actor/Foo.java | 2 +- ...a => NestedTransactionalActiveObject.java} | 7 +- ...ul.java => TransactionalActiveObject.java} | 11 +-- ...NestedTransactionalActiveObjectSpec.scala} | 38 +++++----- .../src/test/scala/RemoteSupervisorSpec.scala | 43 ++++++----- ...RemoteTransactionalActiveObjectSpec.scala} | 44 ++++++----- akka-core/src/test/scala/StmSpec.scala | 3 +- akka-core/src/test/scala/SupervisorSpec.scala | 66 +++++++++++++++++ ...la => TransactionalActiveObjectSpec.scala} | 24 +++--- ...ryActorSpec.scala => TransactorSpec.scala} | 46 ++++++------ .../2.2/aspectwerkz-nodeps-jdk5-2.2.jar | Bin 1876389 -> 1876580 bytes 17 files changed, 225 insertions(+), 166 deletions(-) rename akka-core/src/test/java/se/scalablesolutions/akka/actor/{InMemFailer.java => ActiveObjectFailer.java} (62%) rename akka-core/src/test/java/se/scalablesolutions/akka/actor/{InMemStatefulNested.java => NestedTransactionalActiveObject.java} (87%) rename akka-core/src/test/java/se/scalablesolutions/akka/actor/{InMemStateful.java => TransactionalActiveObject.java} (82%) rename akka-core/src/test/scala/{InMemNestedStateSpec.scala => NestedTransactionalActiveObjectSpec.scala} (79%) rename akka-core/src/test/scala/{RemoteInMemoryStateSpec.scala => RemoteTransactionalActiveObjectSpec.scala} (67%) rename akka-core/src/test/scala/{InMemoryStateSpec.scala => TransactionalActiveObjectSpec.scala} (82%) rename akka-core/src/test/scala/{InMemoryActorSpec.scala => TransactorSpec.scala} (89%) diff --git a/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/InMemStateful.java b/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/InMemStateful.java index 411fc1d420..221259f6e8 100644 --- a/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/InMemStateful.java +++ b/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/InMemStateful.java @@ -13,6 +13,7 @@ public class InMemStateful { private Ref refState; private boolean isInitialized = false; + @inittransactionalstate public void init() { if (!isInitialized) { mapState = new TransactionalMap(); diff --git a/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/InMemStatefulNested.java b/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/InMemStatefulNested.java index 424e2c03e0..08c89883b0 100644 --- a/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/InMemStatefulNested.java +++ b/akka-active-object-test/src/test/java/se/scalablesolutions/akka/api/InMemStatefulNested.java @@ -11,6 +11,7 @@ public class InMemStatefulNested { private Ref refState; private boolean isInitialized = false; + @inittransactionalstate public void init() { if (!isInitialized) { mapState = new TransactionalMap(); diff --git a/akka-core/src/main/scala/actor/ActorRef.scala b/akka-core/src/main/scala/actor/ActorRef.scala index 1a082ed2b8..d3d9dc28b5 100644 --- a/akka-core/src/main/scala/actor/ActorRef.scala +++ b/akka-core/src/main/scala/actor/ActorRef.scala @@ -1311,53 +1311,62 @@ sealed class LocalActorRef private[akka]( } protected[akka] def restart(reason: Throwable): Unit = { - //_isBeingRestarted = true - Actor.log.info("Restarting actor [%s] configured as PERMANENT.", id) - restartLinkedActors(reason) val failedActor = actorInstance.get failedActor.synchronized { - Actor.log.debug("Restarting linked actors for actor [%s].", id) - Actor.log.debug("Invoking 'preRestart' for failed actor instance [%s].", id) - failedActor.preRestart(reason) - nullOutActorRefReferencesFor(failedActor) - val freshActor = newActor - freshActor.synchronized { - freshActor.init - freshActor.initTransactionalState - actorInstance.set(freshActor) - Actor.log.debug("Invoking 'postRestart' for new actor instance [%s].", id) - freshActor.postRestart(reason) + lifeCycle.get match { + case LifeCycle(scope, _) => { + scope match { + case Permanent => + Actor.log.info("Restarting actor [%s] configured as PERMANENT.", id) + restartLinkedActors(reason) + Actor.log.debug("Restarting linked actors for actor [%s].", id) + Actor.log.debug("Invoking 'preRestart' for failed actor instance [%s].", id) + failedActor.preRestart(reason) + nullOutActorRefReferencesFor(failedActor) + val freshActor = newActor + freshActor.synchronized { + freshActor.init + freshActor.initTransactionalState + actorInstance.set(freshActor) + Actor.log.debug("Invoking 'postRestart' for new actor instance [%s].", id) + freshActor.postRestart(reason) + } + _isBeingRestarted = false + case Temporary => shutDownTemporaryActor(this) + } + } } - _isBeingRestarted = false } } - + protected[akka] def restartLinkedActors(reason: Throwable) = guard.withGuard { linkedActorsAsList.foreach { actorRef => if (actorRef.lifeCycle.isEmpty) actorRef.lifeCycle = Some(LifeCycle(Permanent)) actorRef.lifeCycle.get match { case LifeCycle(scope, _) => { scope match { - case Permanent => - actorRef.restart(reason) - case Temporary => - Actor.log.info("Actor [%s] configured as TEMPORARY and will not be restarted.", actorRef.id) - actorRef.stop - linkedActors.remove(actorRef.uuid) // remove the temporary actor - // if last temporary actor is gone, then unlink me from supervisor - if (linkedActors.isEmpty) { - Actor.log.info( - "All linked actors have died permanently (they were all configured as TEMPORARY)" + - "\n\tshutting down and unlinking supervisor actor as well [%s].", - actorRef.id) - _supervisor.foreach(_ ! UnlinkAndStop(this)) - } + case Permanent => actorRef.restart(reason) + case Temporary => shutDownTemporaryActor(actorRef) } } } } } + private def shutDownTemporaryActor(temporaryActor: ActorRef) = { + Actor.log.info("Actor [%s] configured as TEMPORARY and will not be restarted.", temporaryActor.id) + temporaryActor.stop + linkedActors.remove(temporaryActor.uuid) // remove the temporary actor + // if last temporary actor is gone, then unlink me from supervisor + if (linkedActors.isEmpty) { + Actor.log.info( + "All linked actors have died permanently (they were all configured as TEMPORARY)" + + "\n\tshutting down and unlinking supervisor actor as well [%s].", + temporaryActor.id) + _supervisor.foreach(_ ! UnlinkAndStop(this)) + } + } + protected[akka] def registerSupervisorAsRemoteActor: Option[String] = guard.withGuard { if (_supervisor.isDefined) { RemoteClient.clientFor(remoteAddress.get).registerSupervisorForActor(this) diff --git a/akka-core/src/main/scala/remote/RemoteServer.scala b/akka-core/src/main/scala/remote/RemoteServer.scala index 8bb71ab608..f7bc664725 100644 --- a/akka-core/src/main/scala/remote/RemoteServer.scala +++ b/akka-core/src/main/scala/remote/RemoteServer.scala @@ -425,14 +425,14 @@ class RemoteServerHandler( log.error(e.getCause, "Could not invoke remote active object [%s :: %s]", request.getMethod, request.getTarget) val replyBuilder = RemoteReplyProtocol.newBuilder .setId(request.getId) - .setException(ExceptionProtocol.newBuilder.setClassname(e.getClass.getName).setMessage(e.getMessage).build) + .setException(ExceptionProtocol.newBuilder.setClassname(e.getCause.getClass.getName).setMessage(e.getCause.getMessage).build) .setIsSuccessful(false) .setIsActor(false) if (request.hasSupervisorUuid) replyBuilder.setSupervisorUuid(request.getSupervisorUuid) val replyMessage = replyBuilder.build channel.write(replyMessage) case e: Throwable => - log.error(e.getCause, "Could not invoke remote active object [%s :: %s]", request.getMethod, request.getTarget) + log.error(e, "Could not invoke remote active object [%s :: %s]", request.getMethod, request.getTarget) val replyBuilder = RemoteReplyProtocol.newBuilder .setId(request.getId) .setException(ExceptionProtocol.newBuilder.setClassname(e.getClass.getName).setMessage(e.getMessage).build) diff --git a/akka-core/src/main/scala/stm/Transaction.scala b/akka-core/src/main/scala/stm/Transaction.scala index b4fb0cda4c..80fc65cc55 100644 --- a/akka-core/src/main/scala/stm/Transaction.scala +++ b/akka-core/src/main/scala/stm/Transaction.scala @@ -87,35 +87,7 @@ object Transaction { // --- public methods --------- - def begin = synchronized { - jta.foreach { txContainer => - txContainer.begin - txContainer.registerSynchronization(new StmSynchronization(txContainer, this)) - } - } - - def commit = synchronized { - log.trace("Committing transaction %s", toString) - persistentStateMap.valuesIterator.foreach(_.commit) - status = TransactionStatus.Completed - jta.foreach(_.commit) - } - - def abort = synchronized { - log.trace("Aborting transaction %s", toString) - jta.foreach(_.rollback) - persistentStateMap.valuesIterator.foreach(_.abort) - persistentStateMap.clear - } - - def isNew = synchronized { status == TransactionStatus.New } - - def isActive = synchronized { status == TransactionStatus.Active } - - def isCompleted = synchronized { status == TransactionStatus.Completed } - - def isAborted = synchronized { status == TransactionStatus.Aborted } - + // --- internal methods --------- private def isJtaTxActive(status: Int) = status == Status.STATUS_ACTIVE diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/InMemFailer.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/ActiveObjectFailer.java similarity index 62% rename from akka-core/src/test/java/se/scalablesolutions/akka/actor/InMemFailer.java rename to akka-core/src/test/java/se/scalablesolutions/akka/actor/ActiveObjectFailer.java index 6239c64402..6e30a1a971 100644 --- a/akka-core/src/test/java/se/scalablesolutions/akka/actor/InMemFailer.java +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/ActiveObjectFailer.java @@ -1,6 +1,6 @@ package se.scalablesolutions.akka.actor; -public class InMemFailer implements java.io.Serializable { +public class ActiveObjectFailer implements java.io.Serializable { public int fail() { throw new RuntimeException("expected"); } diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/Foo.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/Foo.java index 7382cb6aef..4c1a80201d 100644 --- a/akka-core/src/test/java/se/scalablesolutions/akka/actor/Foo.java +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/Foo.java @@ -17,7 +17,7 @@ public class Foo extends se.scalablesolutions.akka.serialization.Serializable.Ja } public String longRunning() { try { - Thread.sleep(10000); + Thread.sleep(1000); } catch (InterruptedException e) { } return "test"; diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/InMemStatefulNested.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/NestedTransactionalActiveObject.java similarity index 87% rename from akka-core/src/test/java/se/scalablesolutions/akka/actor/InMemStatefulNested.java rename to akka-core/src/test/java/se/scalablesolutions/akka/actor/NestedTransactionalActiveObject.java index 0b484c1178..af6bb8245c 100644 --- a/akka-core/src/test/java/se/scalablesolutions/akka/actor/InMemStatefulNested.java +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/NestedTransactionalActiveObject.java @@ -5,12 +5,13 @@ import se.scalablesolutions.akka.actor.annotation.inittransactionalstate; import se.scalablesolutions.akka.stm.*; @transactionrequired -public class InMemStatefulNested { +public class NestedTransactionalActiveObject { private TransactionalMap mapState; private TransactionalVector vectorState; private Ref refState; private boolean isInitialized = false; + @inittransactionalstate public void init() { if (!isInitialized) { mapState = new TransactionalMap(); @@ -57,7 +58,7 @@ public class InMemStatefulNested { } - public String failure(String key, String msg, InMemFailer failer) { + public String failure(String key, String msg, ActiveObjectFailer failer) { mapState.put(key, msg); vectorState.add(msg); refState.swap(msg); @@ -66,7 +67,7 @@ public class InMemStatefulNested { } - public void thisMethodHangs(String key, String msg, InMemFailer failer) { + public void thisMethodHangs(String key, String msg, ActiveObjectFailer failer) { setMapState(key, msg); } diff --git a/akka-core/src/test/java/se/scalablesolutions/akka/actor/InMemStateful.java b/akka-core/src/test/java/se/scalablesolutions/akka/actor/TransactionalActiveObject.java similarity index 82% rename from akka-core/src/test/java/se/scalablesolutions/akka/actor/InMemStateful.java rename to akka-core/src/test/java/se/scalablesolutions/akka/actor/TransactionalActiveObject.java index 928692ce07..515f4fafee 100644 --- a/akka-core/src/test/java/se/scalablesolutions/akka/actor/InMemStateful.java +++ b/akka-core/src/test/java/se/scalablesolutions/akka/actor/TransactionalActiveObject.java @@ -7,12 +7,13 @@ import se.scalablesolutions.akka.actor.annotation.inittransactionalstate; import se.scalablesolutions.akka.stm.*; @transactionrequired -public class InMemStateful { +public class TransactionalActiveObject { private TransactionalMap mapState; private TransactionalVector vectorState; private Ref refState; private boolean isInitialized = false; + @inittransactionalstate public void init() { if (!isInitialized) { mapState = new TransactionalMap(); @@ -52,14 +53,14 @@ public class InMemStateful { refState.swap(msg); } - public void success(String key, String msg, InMemStatefulNested nested) { + public void success(String key, String msg, NestedTransactionalActiveObject nested) { mapState.put(key, msg); vectorState.add(msg); refState.swap(msg); nested.success(key, msg); } - public String failure(String key, String msg, InMemFailer failer) { + public String failure(String key, String msg, ActiveObjectFailer failer) { mapState.put(key, msg); vectorState.add(msg); refState.swap(msg); @@ -67,7 +68,7 @@ public class InMemStateful { return msg; } - public String failure(String key, String msg, InMemStatefulNested nested, InMemFailer failer) { + public String failure(String key, String msg, NestedTransactionalActiveObject nested, ActiveObjectFailer failer) { mapState.put(key, msg); vectorState.add(msg); refState.swap(msg); @@ -75,7 +76,7 @@ public class InMemStateful { return msg; } - public void thisMethodHangs(String key, String msg, InMemFailer failer) { + public void thisMethodHangs(String key, String msg, ActiveObjectFailer failer) { setMapState(key, msg); } diff --git a/akka-core/src/test/scala/InMemNestedStateSpec.scala b/akka-core/src/test/scala/NestedTransactionalActiveObjectSpec.scala similarity index 79% rename from akka-core/src/test/scala/InMemNestedStateSpec.scala rename to akka-core/src/test/scala/NestedTransactionalActiveObjectSpec.scala index 3f1aca7049..77f713f57d 100644 --- a/akka-core/src/test/scala/InMemNestedStateSpec.scala +++ b/akka-core/src/test/scala/NestedTransactionalActiveObjectSpec.scala @@ -18,7 +18,7 @@ import se.scalablesolutions.akka.config.JavaConfig._ import se.scalablesolutions.akka.actor._ @RunWith(classOf[JUnitRunner]) -class InMemoryNestedStateSpec extends +class NestedTransactionalActiveObjectSpec extends Spec with ShouldMatchers with BeforeAndAfterAll { @@ -31,13 +31,13 @@ class InMemoryNestedStateSpec extends conf.configure( new RestartStrategy(new AllForOne, 3, 5000, List(classOf[Exception]).toArray), List( - new Component(classOf[InMemStateful], + new Component(classOf[TransactionalActiveObject], new LifeCycle(new Permanent), 10000), - new Component(classOf[InMemStatefulNested], + new Component(classOf[NestedTransactionalActiveObject], new LifeCycle(new Permanent), 10000), - new Component(classOf[InMemFailer], + new Component(classOf[ActiveObjectFailer], new LifeCycle(new Permanent), 10000) ).toArray).supervise @@ -50,11 +50,11 @@ class InMemoryNestedStateSpec extends describe("Transactional nested in-memory Active Object") { it("map should not rollback state for stateful server in case of success") { - val stateful = conf.getInstance(classOf[InMemStateful]) + val stateful = conf.getInstance(classOf[TransactionalActiveObject]) stateful.init stateful.setMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "init") // set init state Thread.sleep(100) - val nested = conf.getInstance(classOf[InMemStatefulNested]) + val nested = conf.getInstance(classOf[NestedTransactionalActiveObject]) nested.init nested.setMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "init") // set init state Thread.sleep(100) @@ -65,15 +65,15 @@ class InMemoryNestedStateSpec extends } it("map should rollback state for stateful server in case of failure") { - val stateful = conf.getInstance(classOf[InMemStateful]) + val stateful = conf.getInstance(classOf[TransactionalActiveObject]) stateful.init stateful.setMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init") // set init state Thread.sleep(100) - val nested = conf.getInstance(classOf[InMemStatefulNested]) + val nested = conf.getInstance(classOf[NestedTransactionalActiveObject]) nested.init nested.setMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init") // set init state Thread.sleep(100) - val failer = conf.getInstance(classOf[InMemFailer]) + val failer = conf.getInstance(classOf[ActiveObjectFailer]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", nested, failer) Thread.sleep(100) @@ -85,11 +85,11 @@ class InMemoryNestedStateSpec extends } it("vector should not rollback state for stateful server in case of success") { - val stateful = conf.getInstance(classOf[InMemStateful]) + val stateful = conf.getInstance(classOf[TransactionalActiveObject]) stateful.init stateful.setVectorState("init") // set init state Thread.sleep(100) - val nested = conf.getInstance(classOf[InMemStatefulNested]) + val nested = conf.getInstance(classOf[NestedTransactionalActiveObject]) nested.init Thread.sleep(100) nested.setVectorState("init") // set init state @@ -102,15 +102,15 @@ class InMemoryNestedStateSpec extends } it("vector should rollback state for stateful server in case of failure") { - val stateful = conf.getInstance(classOf[InMemStateful]) + val stateful = conf.getInstance(classOf[TransactionalActiveObject]) stateful.init stateful.setVectorState("init") // set init state Thread.sleep(100) - val nested = conf.getInstance(classOf[InMemStatefulNested]) + val nested = conf.getInstance(classOf[NestedTransactionalActiveObject]) nested.init nested.setVectorState("init") // set init state Thread.sleep(100) - val failer = conf.getInstance(classOf[InMemFailer]) + val failer = conf.getInstance(classOf[ActiveObjectFailer]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", nested, failer) Thread.sleep(100) @@ -122,9 +122,9 @@ class InMemoryNestedStateSpec extends } it("ref should not rollback state for stateful server in case of success") { - val stateful = conf.getInstance(classOf[InMemStateful]) + val stateful = conf.getInstance(classOf[TransactionalActiveObject]) stateful.init - val nested = conf.getInstance(classOf[InMemStatefulNested]) + val nested = conf.getInstance(classOf[NestedTransactionalActiveObject]) nested.init stateful.setRefState("init") // set init state Thread.sleep(100) @@ -138,15 +138,15 @@ class InMemoryNestedStateSpec extends } it("ref should rollback state for stateful server in case of failure") { - val stateful = conf.getInstance(classOf[InMemStateful]) + val stateful = conf.getInstance(classOf[TransactionalActiveObject]) stateful.init - val nested = conf.getInstance(classOf[InMemStatefulNested]) + val nested = conf.getInstance(classOf[NestedTransactionalActiveObject]) nested.init stateful.setRefState("init") // set init state Thread.sleep(100) nested.setRefState("init") // set init state Thread.sleep(100) - val failer = conf.getInstance(classOf[InMemFailer]) + val failer = conf.getInstance(classOf[ActiveObjectFailer]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", nested, failer) Thread.sleep(100) diff --git a/akka-core/src/test/scala/RemoteSupervisorSpec.scala b/akka-core/src/test/scala/RemoteSupervisorSpec.scala index 0fcefc3cd3..d5503b2a7a 100644 --- a/akka-core/src/test/scala/RemoteSupervisorSpec.scala +++ b/akka-core/src/test/scala/RemoteSupervisorSpec.scala @@ -7,6 +7,7 @@ package se.scalablesolutions.akka.actor import java.util.concurrent.{LinkedBlockingQueue, TimeUnit, BlockingQueue} import se.scalablesolutions.akka.serialization.BinaryString import se.scalablesolutions.akka.config.ScalaConfig._ +import se.scalablesolutions.akka.config.Config import se.scalablesolutions.akka.remote.{RemoteNode, RemoteServer} import se.scalablesolutions.akka.OneWay import se.scalablesolutions.akka.dispatch.Dispatchers @@ -71,19 +72,21 @@ object Log { } } +object RemoteSupervisorSpec { + val HOSTNAME = "localhost" + val PORT = 9988 + var server: RemoteServer = null +} + /** * @author Jonas Bonér */ class RemoteSupervisorSpec extends JUnitSuite { + import RemoteSupervisorSpec._ + Config.config - se.scalablesolutions.akka.config.Config.config - - new Thread(new Runnable() { - def run = { - RemoteNode.start(RemoteServer.HOSTNAME, 9988) - } - }).start - Thread.sleep(1000) + server = new RemoteServer() + server.start(HOSTNAME, PORT) var pingpong1: ActorRef = _ var pingpong2: ActorRef = _ @@ -460,7 +463,7 @@ class RemoteSupervisorSpec extends JUnitSuite { // implementation of the Actors we want to use. pingpong1 = actorOf[RemotePingPong1Actor] - pingpong1.makeRemote(RemoteServer.HOSTNAME, 9988) + pingpong1.makeRemote(HOSTNAME, PORT) pingpong1.start val factory = SupervisorFactory( @@ -476,7 +479,7 @@ class RemoteSupervisorSpec extends JUnitSuite { def getSingleActorOneForOneSupervisor: Supervisor = { pingpong1 = actorOf[RemotePingPong1Actor] - pingpong1.makeRemote(RemoteServer.HOSTNAME, 9988) + pingpong1.makeRemote(HOSTNAME, PORT) pingpong1.start val factory = SupervisorFactory( @@ -491,13 +494,13 @@ class RemoteSupervisorSpec extends JUnitSuite { def getMultipleActorsAllForOneConf: Supervisor = { pingpong1 = actorOf[RemotePingPong1Actor] - pingpong1.makeRemote(RemoteServer.HOSTNAME, 9988) + pingpong1.makeRemote(HOSTNAME, PORT) pingpong1.start pingpong2 = actorOf[RemotePingPong2Actor] - pingpong2.makeRemote(RemoteServer.HOSTNAME, 9988) + pingpong2.makeRemote(HOSTNAME, PORT) pingpong2.start pingpong3 = actorOf[RemotePingPong3Actor] - pingpong3.makeRemote(RemoteServer.HOSTNAME, 9988) + pingpong3.makeRemote(HOSTNAME, PORT) pingpong3.start val factory = SupervisorFactory( @@ -520,15 +523,15 @@ class RemoteSupervisorSpec extends JUnitSuite { def getMultipleActorsOneForOneConf: Supervisor = { pingpong1 = actorOf[RemotePingPong1Actor] - pingpong1.makeRemote(RemoteServer.HOSTNAME, 9988) + pingpong1.makeRemote(HOSTNAME, PORT) pingpong1 = actorOf[RemotePingPong1Actor] - pingpong1.makeRemote(RemoteServer.HOSTNAME, 9988) + pingpong1.makeRemote(HOSTNAME, PORT) pingpong1.start pingpong2 = actorOf[RemotePingPong2Actor] - pingpong2.makeRemote(RemoteServer.HOSTNAME, 9988) + pingpong2.makeRemote(HOSTNAME, PORT) pingpong2.start pingpong3 = actorOf[RemotePingPong3Actor] - pingpong3.makeRemote(RemoteServer.HOSTNAME, 9988) + pingpong3.makeRemote(HOSTNAME, PORT) pingpong3.start val factory = SupervisorFactory( @@ -551,13 +554,13 @@ class RemoteSupervisorSpec extends JUnitSuite { def getNestedSupervisorsAllForOneConf: Supervisor = { pingpong1 = actorOf[RemotePingPong1Actor] - pingpong1.makeRemote(RemoteServer.HOSTNAME, 9988) + pingpong1.makeRemote(HOSTNAME, PORT) pingpong1.start pingpong2 = actorOf[RemotePingPong2Actor] - pingpong2.makeRemote(RemoteServer.HOSTNAME, 9988) + pingpong2.makeRemote(HOSTNAME, PORT) pingpong2.start pingpong3 = actorOf[RemotePingPong3Actor] - pingpong3.makeRemote(RemoteServer.HOSTNAME, 9988) + pingpong3.makeRemote(HOSTNAME, PORT) pingpong3.start val factory = SupervisorFactory( diff --git a/akka-core/src/test/scala/RemoteInMemoryStateSpec.scala b/akka-core/src/test/scala/RemoteTransactionalActiveObjectSpec.scala similarity index 67% rename from akka-core/src/test/scala/RemoteInMemoryStateSpec.scala rename to akka-core/src/test/scala/RemoteTransactionalActiveObjectSpec.scala index 57e4efb827..ac4f41feb3 100644 --- a/akka-core/src/test/scala/RemoteInMemoryStateSpec.scala +++ b/akka-core/src/test/scala/RemoteTransactionalActiveObjectSpec.scala @@ -13,40 +13,44 @@ import org.junit.runner.RunWith import se.scalablesolutions.akka.config.Config import se.scalablesolutions.akka.config.ActiveObjectConfigurator -import se.scalablesolutions.akka.remote.RemoteNode +import se.scalablesolutions.akka.remote.{RemoteNode, RemoteServer} + +object RemoteTransactionalActiveObjectSpec { + val HOSTNAME = "localhost" + val PORT = 9988 + var server: RemoteServer = null +} @RunWith(classOf[JUnitRunner]) -class RemoteInMemoryStateSpec extends +class RemoteTransactionalActiveObjectSpec extends Spec with ShouldMatchers with BeforeAndAfterAll { + import RemoteTransactionalActiveObjectSpec._ + Config.config + + server = new RemoteServer() + server.start(HOSTNAME, PORT) + private val conf = new ActiveObjectConfigurator - private var messageLog = "" - - override def beforeAll = { - Config.config - new Thread(new Runnable { - def run = RemoteNode.start - }).start - Thread.sleep(1000) - } + private var messageLog = "" override def afterAll = conf.stop describe("Remote transactional in-memory Active Object ") { it("map should not rollback state for stateful server in case of success") { - val stateful = ActiveObject.newRemoteInstance(classOf[InMemStateful], 1000, "localhost", 9999) + val stateful = ActiveObject.newRemoteInstance(classOf[TransactionalActiveObject], 1000, HOSTNAME, PORT) stateful.setMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "init") // set init state stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") // transactionrequired stateful.getMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess") should equal("new state") } it("map should rollback state for stateful server in case of failure") { - val stateful = ActiveObject.newRemoteInstance(classOf[InMemStateful], 1000, "localhost", 9999) + val stateful = ActiveObject.newRemoteInstance(classOf[TransactionalActiveObject], 1000, HOSTNAME, PORT) stateful.setMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init") // set init state - val failer =ActiveObject.newRemoteInstance(classOf[InMemFailer], 1000, "localhost", 9999) //conf.getInstance(classOf[InMemFailer]) + val failer =ActiveObject.newRemoteInstance(classOf[ActiveObjectFailer], 1000, HOSTNAME, PORT) //conf.getInstance(classOf[ActiveObjectFailer]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) // call failing transactionrequired method fail("should have thrown an exception") @@ -55,16 +59,16 @@ class RemoteInMemoryStateSpec extends } it("vector should not rollback state for stateful server in case of success") { - val stateful = ActiveObject.newRemoteInstance(classOf[InMemStateful], 1000, "localhost", 9999) + val stateful = ActiveObject.newRemoteInstance(classOf[TransactionalActiveObject], 1000, HOSTNAME, PORT) stateful.setVectorState("init") // set init state stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") // transactionrequired stateful.getVectorState should equal("new state") } it("vector should rollback state for stateful server in case of failure") { - val stateful = ActiveObject.newRemoteInstance(classOf[InMemStateful], 1000, "localhost", 9999) + val stateful = ActiveObject.newRemoteInstance(classOf[TransactionalActiveObject], 1000, HOSTNAME, PORT) stateful.setVectorState("init") // set init state - val failer =ActiveObject.newRemoteInstance(classOf[InMemFailer], 1000, "localhost", 9999) //conf.getInstance(classOf[InMemFailer]) + val failer =ActiveObject.newRemoteInstance(classOf[ActiveObjectFailer], 1000, HOSTNAME, PORT) //conf.getInstance(classOf[ActiveObjectFailer]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) // call failing transactionrequired method fail("should have thrown an exception") @@ -73,16 +77,16 @@ class RemoteInMemoryStateSpec extends } it("ref should not rollback state for stateful server in case of success") { - val stateful = ActiveObject.newRemoteInstance(classOf[InMemStateful], 1000, "localhost", 9999) + val stateful = ActiveObject.newRemoteInstance(classOf[TransactionalActiveObject], 1000, HOSTNAME, PORT) stateful.setRefState("init") // set init state stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") // transactionrequired stateful.getRefState should equal("new state") } it("ref should rollback state for stateful server in case of failure") { - val stateful = ActiveObject.newRemoteInstance(classOf[InMemStateful], 1000, "localhost", 9999) + val stateful = ActiveObject.newRemoteInstance(classOf[TransactionalActiveObject], 1000, HOSTNAME, PORT) stateful.setRefState("init") // set init state - val failer =ActiveObject.newRemoteInstance(classOf[InMemFailer], 1000, "localhost", 9999) //conf.getInstance(classOf[InMemFailer]) + val failer =ActiveObject.newRemoteInstance(classOf[ActiveObjectFailer], 1000, HOSTNAME, PORT) //conf.getInstance(classOf[ActiveObjectFailer]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) // call failing transactionrequired method fail("should have thrown an exception") diff --git a/akka-core/src/test/scala/StmSpec.scala b/akka-core/src/test/scala/StmSpec.scala index cfb057a42f..16912726a9 100644 --- a/akka-core/src/test/scala/StmSpec.scala +++ b/akka-core/src/test/scala/StmSpec.scala @@ -100,7 +100,7 @@ class StmSpec extends } } } - +/* describe("Transactor") { it("should be able receive message sent with !! and pass it along to nested transactor with !! and receive reply; multiple times in a row") { import GlobalTransactionVectorTestActor._ @@ -121,6 +121,7 @@ class StmSpec extends size4 should equal(3) } } + */ } object GlobalTransactionVectorTestActor { diff --git a/akka-core/src/test/scala/SupervisorSpec.scala b/akka-core/src/test/scala/SupervisorSpec.scala index bcf8496582..0e07140182 100644 --- a/akka-core/src/test/scala/SupervisorSpec.scala +++ b/akka-core/src/test/scala/SupervisorSpec.scala @@ -5,6 +5,7 @@ package se.scalablesolutions.akka.actor import se.scalablesolutions.akka.config.ScalaConfig._ +import se.scalablesolutions.akka.config.OneForOneStrategy import se.scalablesolutions.akka.dispatch.Dispatchers import se.scalablesolutions.akka.{OneWay, Die, Ping} import Actor._ @@ -75,6 +76,33 @@ object SupervisorSpec { messageLog.put(reason.getMessage) } } + + class TemporaryActor extends Actor { + import self._ + lifeCycle = Some(LifeCycle(Temporary)) + def receive = { + case Ping => + messageLog.put("ping") + reply("pong") + case Die => + println("******************** GOT DIE 3") + throw new RuntimeException("DIE") + } + + override def postRestart(reason: Throwable) { + println("******************** restart temporary") + messageLog.put(reason.getMessage) + } + } + + class Master extends Actor { + self.trapExit = classOf[Exception] :: Nil + self.faultHandler = Some(OneForOneStrategy(5, 1000)) + val temp = self.spawnLink[TemporaryActor] + override def receive = { + case Die => temp !! (Die, 5000) + } + } } /** @@ -86,7 +114,9 @@ class SupervisorSpec extends JUnitSuite { var pingpong1: ActorRef = _ var pingpong2: ActorRef = _ var pingpong3: ActorRef = _ + var temporaryActor: ActorRef = _ +/* @Test def shouldStartServer = { clearMessageLogs val sup = getSingleActorAllForOneSupervisor @@ -96,6 +126,30 @@ class SupervisorSpec extends JUnitSuite { (pingpong1 !! (Ping, 5000)).getOrElse("nil") } } +*/ + @Test def shoulNotRestartProgrammaticallyLinkedTemporaryActor = { + clearMessageLogs + val master = actorOf[Master].start + + intercept[RuntimeException] { + master !! (Die, 5000) + } + + Thread.sleep(1000) + assert(messageLog.size === 0) + } + + @Test def shoulNotRestartTemporaryActor = { + clearMessageLogs + val sup = getTemporaryActorAllForOneSupervisor + + intercept[RuntimeException] { + temporaryActor !! (Die, 5000) + } + + Thread.sleep(1000) + assert(messageLog.size === 0) + } @Test def shouldStartServerForNestedSupervisorHierarchy = { clearMessageLogs @@ -445,6 +499,18 @@ class SupervisorSpec extends JUnitSuite { // ============================================= // Create some supervisors with different configurations + def getTemporaryActorAllForOneSupervisor: Supervisor = { + temporaryActor = actorOf[TemporaryActor].start + + Supervisor( + SupervisorConfig( + RestartStrategy(AllForOne, 3, 5000, List(classOf[Exception])), + Supervise( + temporaryActor, + LifeCycle(Temporary)) + :: Nil)) + } + def getSingleActorAllForOneSupervisor: Supervisor = { pingpong1 = actorOf[PingPong1Actor].start diff --git a/akka-core/src/test/scala/InMemoryStateSpec.scala b/akka-core/src/test/scala/TransactionalActiveObjectSpec.scala similarity index 82% rename from akka-core/src/test/scala/InMemoryStateSpec.scala rename to akka-core/src/test/scala/TransactionalActiveObjectSpec.scala index d4f92c9759..77de00cf9a 100644 --- a/akka-core/src/test/scala/InMemoryStateSpec.scala +++ b/akka-core/src/test/scala/TransactionalActiveObjectSpec.scala @@ -18,7 +18,7 @@ import se.scalablesolutions.akka.config.JavaConfig._ import se.scalablesolutions.akka.actor._ @RunWith(classOf[JUnitRunner]) -class InMemoryStateSpec extends +class TransactionalActiveObjectSpec extends Spec with ShouldMatchers with BeforeAndAfterAll { @@ -31,11 +31,11 @@ class InMemoryStateSpec extends conf.configure( new RestartStrategy(new AllForOne, 3, 5000, List(classOf[Exception]).toArray), List( - new Component(classOf[InMemStateful], + new Component(classOf[TransactionalActiveObject], new LifeCycle(new Permanent), //new RestartCallbacks("preRestart", "postRestart")), 10000), - new Component(classOf[InMemFailer], + new Component(classOf[ActiveObjectFailer], new LifeCycle(new Permanent), 10000)).toArray ).supervise @@ -48,7 +48,7 @@ class InMemoryStateSpec extends describe("Transactional in-memory Active Object ") { it("map should not rollback state for stateful server in case of success") { - val stateful = conf.getInstance(classOf[InMemStateful]) + val stateful = conf.getInstance(classOf[TransactionalActiveObject]) stateful.init stateful.setMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "init") stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") @@ -56,10 +56,10 @@ class InMemoryStateSpec extends } it("map should rollback state for stateful server in case of failure") { - val stateful = conf.getInstance(classOf[InMemStateful]) + val stateful = conf.getInstance(classOf[TransactionalActiveObject]) stateful.init stateful.setMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init") - val failer = conf.getInstance(classOf[InMemFailer]) + val failer = conf.getInstance(classOf[ActiveObjectFailer]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) fail("should have thrown an exception") @@ -68,10 +68,10 @@ class InMemoryStateSpec extends } it("vector should rollback state for stateful server in case of failure") { - val stateful = conf.getInstance(classOf[InMemStateful]) + val stateful = conf.getInstance(classOf[TransactionalActiveObject]) stateful.init stateful.setVectorState("init") // set init state - val failer = conf.getInstance(classOf[InMemFailer]) + val failer = conf.getInstance(classOf[ActiveObjectFailer]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) fail("should have thrown an exception") @@ -80,7 +80,7 @@ class InMemoryStateSpec extends } it("vector should not rollback state for stateful server in case of success") { - val stateful = conf.getInstance(classOf[InMemStateful]) + val stateful = conf.getInstance(classOf[TransactionalActiveObject]) stateful.init stateful.setVectorState("init") // set init state stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") @@ -88,10 +88,10 @@ class InMemoryStateSpec extends } it("ref should rollback state for stateful server in case of failure") { - val stateful = conf.getInstance(classOf[InMemStateful]) + val stateful = conf.getInstance(classOf[TransactionalActiveObject]) stateful.init stateful.setRefState("init") // set init state - val failer = conf.getInstance(classOf[InMemFailer]) + val failer = conf.getInstance(classOf[ActiveObjectFailer]) try { stateful.failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) fail("should have thrown an exception") @@ -100,7 +100,7 @@ class InMemoryStateSpec extends } it("ref should not rollback state for stateful server in case of success") { - val stateful = conf.getInstance(classOf[InMemStateful]) + val stateful = conf.getInstance(classOf[TransactionalActiveObject]) stateful.init stateful.setRefState("init") // set init state stateful.success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") diff --git a/akka-core/src/test/scala/InMemoryActorSpec.scala b/akka-core/src/test/scala/TransactorSpec.scala similarity index 89% rename from akka-core/src/test/scala/InMemoryActorSpec.scala rename to akka-core/src/test/scala/TransactorSpec.scala index fcc54399e2..213863b377 100644 --- a/akka-core/src/test/scala/InMemoryActorSpec.scala +++ b/akka-core/src/test/scala/TransactorSpec.scala @@ -7,7 +7,7 @@ import org.junit.Test import se.scalablesolutions.akka.stm.{Ref, TransactionalMap, TransactionalVector} import Actor._ -object InMemoryActorSpec { +object TransactorSpec { case class GetMapState(key: String) case object GetVectorState case object GetVectorSize @@ -27,9 +27,9 @@ object InMemoryActorSpec { case object GetNotifier } -import InMemoryActorSpec._ +import TransactorSpec._ -class InMemStatefulActor(expectedInvocationCount: Int) extends Transactor { +class StatefulTransactor(expectedInvocationCount: Int) extends Transactor { def this() = this(0) self.timeout = 5000 @@ -101,7 +101,7 @@ class InMemStatefulActor(expectedInvocationCount: Int) extends Transactor { } @serializable -class InMemFailerActor extends Transactor { +class FailerTransactor extends Transactor { def receive = { case "Failure" => @@ -109,10 +109,10 @@ class InMemFailerActor extends Transactor { } } -class InMemoryActorSpec extends JUnitSuite { +class TransactorSpec extends JUnitSuite { @Test def shouldOneWayMapShouldNotRollbackStateForStatefulServerInCaseOfSuccess = { - val stateful = actorOf(new InMemStatefulActor(2)) + val stateful = actorOf(new StatefulTransactor(2)) stateful.start stateful ! SetMapStateOneWay("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "init") // set init state stateful ! SuccessOneWay("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") // transactionrequired @@ -123,7 +123,7 @@ class InMemoryActorSpec extends JUnitSuite { @Test def shouldMapShouldNotRollbackStateForStatefulServerInCaseOfSuccess = { - val stateful = actorOf[InMemStatefulActor] + val stateful = actorOf[StatefulTransactor] stateful.start stateful !! SetMapState("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "init") // set init state stateful !! Success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") // transactionrequired @@ -132,9 +132,9 @@ class InMemoryActorSpec extends JUnitSuite { @Test def shouldOneWayMapShouldRollbackStateForStatefulServerInCaseOfFailure = { - val stateful = actorOf(new InMemStatefulActor(2)) + val stateful = actorOf(new StatefulTransactor(2)) stateful.start - val failer = actorOf[InMemFailerActor] + val failer = actorOf[FailerTransactor] failer.start stateful ! SetMapStateOneWay("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init") // set init state stateful ! FailureOneWay("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) // call failing transactionrequired method @@ -145,10 +145,10 @@ class InMemoryActorSpec extends JUnitSuite { @Test def shouldMapShouldRollbackStateForStatefulServerInCaseOfFailure = { - val stateful = actorOf[InMemStatefulActor] + val stateful = actorOf[StatefulTransactor] stateful.start stateful !! SetMapState("testShouldRollbackStateForStatefulServerInCaseOfFailure", "init") // set init state - val failer = actorOf[InMemFailerActor] + val failer = actorOf[FailerTransactor] failer.start try { stateful !! Failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) // call failing transactionrequired method @@ -159,7 +159,7 @@ class InMemoryActorSpec extends JUnitSuite { @Test def shouldOneWayVectorShouldNotRollbackStateForStatefulServerInCaseOfSuccess = { - val stateful = actorOf(new InMemStatefulActor(2)) + val stateful = actorOf(new StatefulTransactor(2)) stateful.start stateful ! SetVectorStateOneWay("init") // set init state stateful ! SuccessOneWay("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") // transactionrequired @@ -170,7 +170,7 @@ class InMemoryActorSpec extends JUnitSuite { @Test def shouldVectorShouldNotRollbackStateForStatefulServerInCaseOfSuccess = { - val stateful = actorOf[InMemStatefulActor] + val stateful = actorOf[StatefulTransactor] stateful.start stateful !! SetVectorState("init") // set init state stateful !! Success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") // transactionrequired @@ -179,11 +179,11 @@ class InMemoryActorSpec extends JUnitSuite { @Test def shouldOneWayVectorShouldRollbackStateForStatefulServerInCaseOfFailure = { - val stateful = actorOf(new InMemStatefulActor(2)) + val stateful = actorOf(new StatefulTransactor(2)) stateful.start stateful ! SetVectorStateOneWay("init") // set init state Thread.sleep(1000) - val failer = actorOf[InMemFailerActor] + val failer = actorOf[FailerTransactor] failer.start stateful ! FailureOneWay("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) // call failing transactionrequired method val notifier = (stateful !! GetNotifier).as[CountDownLatch] @@ -193,10 +193,10 @@ class InMemoryActorSpec extends JUnitSuite { @Test def shouldVectorShouldRollbackStateForStatefulServerInCaseOfFailure = { - val stateful = actorOf[InMemStatefulActor] + val stateful = actorOf[StatefulTransactor] stateful.start stateful !! SetVectorState("init") // set init state - val failer = actorOf[InMemFailerActor] + val failer = actorOf[FailerTransactor] failer.start try { stateful !! Failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) // call failing transactionrequired method @@ -207,7 +207,7 @@ class InMemoryActorSpec extends JUnitSuite { @Test def shouldOneWayRefShouldNotRollbackStateForStatefulServerInCaseOfSuccess = { - val stateful = actorOf(new InMemStatefulActor(2)) + val stateful = actorOf(new StatefulTransactor(2)) stateful.start stateful ! SetRefStateOneWay("init") // set init state stateful ! SuccessOneWay("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") // transactionrequired @@ -218,7 +218,7 @@ class InMemoryActorSpec extends JUnitSuite { @Test def shouldRefShouldNotRollbackStateForStatefulServerInCaseOfSuccess = { - val stateful = actorOf[InMemStatefulActor] + val stateful = actorOf[StatefulTransactor] stateful.start stateful !! SetRefState("init") // set init state stateful !! Success("testShouldNotRollbackStateForStatefulServerInCaseOfSuccess", "new state") // transactionrequired @@ -227,11 +227,11 @@ class InMemoryActorSpec extends JUnitSuite { @Test def shouldOneWayRefShouldRollbackStateForStatefulServerInCaseOfFailure = { - val stateful = actorOf(new InMemStatefulActor(2)) + val stateful = actorOf(new StatefulTransactor(2)) stateful.start stateful ! SetRefStateOneWay("init") // set init state Thread.sleep(1000) - val failer = actorOf[InMemFailerActor] + val failer = actorOf[FailerTransactor] failer.start stateful ! FailureOneWay("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) // call failing transactionrequired method val notifier = (stateful !! GetNotifier).as[CountDownLatch] @@ -241,10 +241,10 @@ class InMemoryActorSpec extends JUnitSuite { @Test def shouldRefShouldRollbackStateForStatefulServerInCaseOfFailure = { - val stateful = actorOf[InMemStatefulActor] + val stateful = actorOf[StatefulTransactor] stateful.start stateful !! SetRefState("init") // set init state - val failer = actorOf[InMemFailerActor] + val failer = actorOf[FailerTransactor] failer.start try { stateful !! Failure("testShouldRollbackStateForStatefulServerInCaseOfFailure", "new state", failer) // call failing transactionrequired method diff --git a/embedded-repo/org/codehaus/aspectwerkz/aspectwerkz-nodeps-jdk5/2.2/aspectwerkz-nodeps-jdk5-2.2.jar b/embedded-repo/org/codehaus/aspectwerkz/aspectwerkz-nodeps-jdk5/2.2/aspectwerkz-nodeps-jdk5-2.2.jar index 69214f54d0bdfcedbb0ea46b2c0fcc085aa41baa..38a57f3e69c28f806d4d0a0f19fb0160b5e5cf3e 100644 GIT binary patch delta 24008 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 UnD%x|k6kF^#3t1z#lXM-08LSQfdBvi delta 23606 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