diff --git a/akka-core/src/main/scala/actor/ActiveObject.scala b/akka-core/src/main/scala/actor/ActiveObject.scala index ae36bc4df2..e242ec8910 100644 --- a/akka-core/src/main/scala/actor/ActiveObject.scala +++ b/akka-core/src/main/scala/actor/ActiveObject.scala @@ -210,25 +210,24 @@ object ActiveObject { } private[akka] object AspectInitRegistry { - private val inits = new java.util.concurrent.ConcurrentHashMap[AnyRef, AspectInit] + private val initializations = new java.util.concurrent.ConcurrentHashMap[AnyRef, AspectInit] def initFor(target: AnyRef) = { - val init = inits.get(target) - inits.remove(target) + val init = initializations.get(target) + initializations.remove(target) init } - def register(target: AnyRef, init: AspectInit) = inits.put(target, init) + def register(target: AnyRef, init: AspectInit) = initializations.put(target, init) } private[akka] sealed case class AspectInit( val target: Class[_], val actor: Dispatcher, val remoteAddress: Option[InetSocketAddress], - val timeout: Long){ - - def this(target: Class[_],actor: Dispatcher, timeout: Long) = this(target,actor,None,timeout) - } + val timeout: Long) { + def this(target: Class[_],actor: Dispatcher, timeout: Long) = this(target, actor, None, timeout) +} /** * AspectWerkz Aspect that is turning POJOs into Active Object. diff --git a/akka-spring/src/main/java/se/scalablesolutions/akka/spring/AkkaSpringInterceptor.java b/akka-spring/src/main/java/se/scalablesolutions/akka/spring/AkkaSpringInterceptor.java index 1d4bc1245d..456dd15572 100644 --- a/akka-spring/src/main/java/se/scalablesolutions/akka/spring/AkkaSpringInterceptor.java +++ b/akka-spring/src/main/java/se/scalablesolutions/akka/spring/AkkaSpringInterceptor.java @@ -47,13 +47,15 @@ public class AkkaSpringInterceptor extends ActiveObjectAspect implements MethodI public Object invoke(MethodInvocation methodInvocation) throws Throwable { Dispatcher dispatcher = new Dispatcher(isTransactional()); dispatcher.start(); - AspectInitRegistry.register(methodInvocation.getThis(), new AspectInit( - methodInvocation.getThis().getClass(), - dispatcher, - TIME_OUT)); - Object result = this.invoke(AkkaSpringJoinPointWrapper.createSpringAkkaAspectWerkzWrapper(methodInvocation)); - dispatcher.stop(); - return result; + try { + AspectInitRegistry.register(methodInvocation.getThis(), new AspectInit( + methodInvocation.getThis().getClass(), + dispatcher, + TIME_OUT)); + return this.invoke(AkkaSpringJoinPointWrapper.createSpringAkkaAspectWerkzWrapper(methodInvocation)); + } finally { + dispatcher.stop(); + } } @Override diff --git a/akka-spring/src/test/java/se/scalablesolutions/akka/spring/AkkaSpringInterceptorTest.java b/akka-spring/src/test/java/se/scalablesolutions/akka/spring/AkkaSpringInterceptorTest.java index d73dcbd340..73c08adeca 100644 --- a/akka-spring/src/test/java/se/scalablesolutions/akka/spring/AkkaSpringInterceptorTest.java +++ b/akka-spring/src/test/java/se/scalablesolutions/akka/spring/AkkaSpringInterceptorTest.java @@ -17,10 +17,28 @@ public class AkkaSpringInterceptorTest extends TestCase { return new TestSuite(AkkaSpringInterceptorTest.class); } - public void testInvokingAkkaEnabledSpringBean() { + public void testInvokingAkkaEnabledSpringBeanMethodWithReturnValue() { ApplicationContext context = new ClassPathXmlApplicationContext("spring-test-config.xml"); MyService myService = (MyService) context.getBean("actorBeanService"); - Object obj = myService.getNumbers(12, "vfsh"); + Object obj = myService.getNumbers(12); assertEquals(new Integer(12), obj); } + + public void testThatAkkaEnabledSpringBeanMethodCallIsInvokedInADifferentThreadThanTheTest() { + ApplicationContext context = new ClassPathXmlApplicationContext("spring-test-config.xml"); + MyService myService = (MyService) context.getBean("actorBeanService"); + assertNotSame(Thread.currentThread().getName(), myService.getThreadName()); + } + + public void testInvokingAkkaEnabledSpringBeanMethodWithTransactionalMethod() { + ApplicationContext context = new ClassPathXmlApplicationContext("spring-test-config.xml"); + MyService myService = (MyService) context.getBean("actorBeanService"); + myService.init(); + myService.setMapState("key", "value"); + myService.setRefState("value"); + myService.setVectorState("value"); + assertEquals("value", myService.getMapState("key")); + assertEquals("value", myService.getRefState()); + assertEquals("value", myService.getVectorState()); + } } diff --git a/akka-spring/src/test/java/se/scalablesolutions/akka/spring/MyService.java b/akka-spring/src/test/java/se/scalablesolutions/akka/spring/MyService.java index 716b5ad210..117e282af5 100644 --- a/akka-spring/src/test/java/se/scalablesolutions/akka/spring/MyService.java +++ b/akka-spring/src/test/java/se/scalablesolutions/akka/spring/MyService.java @@ -2,19 +2,78 @@ package se.scalablesolutions.akka.spring; import org.springframework.transaction.annotation.Transactional; -//import se.scalablesolutions.akka.annotation.oneway; +import se.scalablesolutions.akka.state.TransactionalState; +import se.scalablesolutions.akka.state.TransactionalRef; +import se.scalablesolutions.akka.state.TransactionalVector; +import se.scalablesolutions.akka.state.TransactionalMap; + +import se.scalablesolutions.akka.annotation.oneway; +import se.scalablesolutions.akka.annotation.prerestart; +import se.scalablesolutions.akka.annotation.postrestart; public class MyService { - public Integer getNumbers(int aTestNumber, String aText) { - return new Integer(aTestNumber); + private TransactionalMap mapState; + private TransactionalVector vectorState; + private TransactionalRef refState; + private boolean isInitialized = false; + + @Transactional + public void init() { + if (!isInitialized) { + mapState = TransactionalState.newMap(); + vectorState = TransactionalState.newVector(); + refState = TransactionalState.newRef(); + isInitialized = true; + } } - //@oneway - public void calculate() { - for (int i = 1; i < 10000; i++) { - System.out.println("i=" + i); - } + public String getThreadName() { + return Thread.currentThread().getName(); + } + + public Integer getNumbers(int aTestNumber) { + return new Integer(aTestNumber); + } + + @Transactional + public String getMapState(String key) { + return (String)mapState.get(key).get(); + } + + @Transactional + public String getVectorState() { + return (String)vectorState.last(); + } + + @Transactional + public String getRefState() { + return (String)refState.get().get(); + } + + @Transactional + public void setMapState(String key, String msg) { + mapState.put(key, msg); + } + + @Transactional + public void setVectorState(String msg) { + vectorState.add(msg); + } + + @Transactional + public void setRefState(String msg) { + refState.swap(msg); + } + + @prerestart + public void preRestart() { + System.out.println("################ PRE RESTART"); + } + + @postrestart + public void postRestart() { + System.out.println("################ POST RESTART"); } }