为什么Akka在使用ScalaTest进行测试时失败并出现“IllegalStateE
以下是我从Akka收到的错误:
[debug] Running TaskDef(com.suredbits.core.util.time.TimeUtilUnitTest,org.scalatest.tools.Framework$$anon$1@7e1522e,false,[SuiteSelector]) [debug] Running TaskDef(com.suredbits.core.address.AddressDAOSystemTest,[SuiteSelector]) [debug] Running TaskDef(com.suredbits.core.policy.PolicyHolderDAOUnitTest,[SuiteSelector]) [debug] Running TaskDef(rpc.ModesTest,[SuiteSelector]) [debug] Running TaskDef(com.suredbits.core.policy.PolicyDAOSystemTest,[SuiteSelector]) java.lang.IllegalStateException: cannot create children while terminating or terminated at akka.actor.dungeon.Children$class.makeChild(Children.scala:199) at akka.actor.dungeon.Children$class.attachChild(Children.scala:41) at akka.actor.ActorCell.attachChild(ActorCell.scala:369) at akka.actor.ActorSystemImpl.systemActorOf(ActorSystem.scala:551) at akka.testkit.TestKitBase$class.$init$(TestKit.scala:125) at akka.testkit.TestKit.<init>(TestKit.scala:718) at com.suredbits.core.policy.PolicyDAOSystemTest.<init>(PolicyDAOSystemTest.scala:34) at com.suredbits.core.policy.PolicyDAOSystemTest.<init>(PolicyDAOSystemTest.scala:46) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:526) at java.lang.Class.newInstance(Class.java:379) at org.scalatest.tools.Framework$ScalaTestTask.execute(Framework.scala:641) at sbt.TestRunner.runTest$1(TestFramework.scala:84) at sbt.TestRunner.run(TestFramework.scala:94) at sbt.TestFramework$$anon$2$$anonfun$$init$$1$$anonfun$apply$8.apply(TestFramework.scala:219) at sbt.TestFramework$$anon$2$$anonfun$$init$$1$$anonfun$apply$8.apply(TestFramework.scala:219) at sbt.TestFramework$.sbt$TestFramework$$withContextLoader(TestFramework.scala:207) at sbt.TestFramework$$anon$2$$anonfun$$init$$1.apply(TestFramework.scala:219) at sbt.TestFramework$$anon$2$$anonfun$$init$$1.apply(TestFramework.scala:219) at sbt.TestFunction.apply(TestFramework.scala:224) at sbt.Tests$.sbt$Tests$$processRunnable$1(Tests.scala:211) at sbt.Tests$$anonfun$makeSerial$1.apply(Tests.scala:217) at sbt.Tests$$anonfun$makeSerial$1.apply(Tests.scala:217) at sbt.std.Transform$$anon$3$$anonfun$apply$2.apply(System.scala:45) at sbt.std.Transform$$anon$3$$anonfun$apply$2.apply(System.scala:45) at sbt.std.Transform$$anon$4.work(System.scala:64) at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:237) at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:237) at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:18) at sbt.Execute.work(Execute.scala:244) at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:237) at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:237) at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:160) at sbt.CompletionService$$anon$2.call(CompletionService.scala:30) at java.util.concurrent.FutureTask.run(FutureTask.java:262) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) at java.util.concurrent.FutureTask.run(FutureTask.java:262) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) [error] Could not run test com.suredbits.core.policy.PolicyDAOSystemTest: java.lang.IllegalStateException: cannot create children while terminating or terminated [debug] Running TaskDef(com.suredbits.core.policy.PolicyDAOUnitTest,[SuiteSelector]) [debug] Running TaskDef(com.suredbits.core.CurrencyUnitsTest,[SuiteSelector]) [debug] Running TaskDef(com.suredbits.core.AddressMonitorUnitTest,[SuiteSelector]) [debug] Running TaskDef(com.suredbits.core.blockexplorer.BlockCypherSvcUnitTest,[SuiteSelector]) [debug] Running TaskDef(com.suredbits.core.address.AddressDAOUnitTest,[SuiteSelector]) [debug] Running TaskDef(com.suredbits.core.protocol.BitcoinAddressTest,[SuiteSelector]) [debug] Running TaskDef(com.suredbits.core.blockexplorer.BlockchainInfoSvcUnitTest,[SuiteSelector]) 这是我试图运行的测试用例: class PolicyDAOSystemTest(actorSystemConfig: ActorSystemConfig) extends TestKit(actorSystemConfig.actorSystem) with ImplicitSender with WordSpecLike with MustMatchers with BeforeAndAfter with ScalaFutures with PolicyDAOComponent with PolicyHolderDAOComponent with DbConfigTest with ActorSystemConfig { import actorSystemConfig.actorSystem._ private val dbManagement = new DbManagement with DbConfigTest // 1 month private val policyDuration = new RichDuration(new Duration(1000 * 60 * 60 * 24 * 30)) private val policyCreation = new RichDateTime(new DateTime) def this() = this(ActorSystemConfig) } 这是ActorSystemConfig的scala代码 trait ActorSystemConfig { val actorSystem: ActorSystem = ActorSystem("My-Actor-System") implicit val timeout = Timeout(2 seconds) } object ActorSystemConfig extends ActorSystemConfig 最后,这是PolicyDAO的源代码. trait PolicyDAOComponent extends CRUDActorComponent { this: PolicyHolderDAOComponent with DbConfig with ActorSystemConfig => import actorSystem._ def policyDAOActor: ActorRef = actorSystem.actorOf(Props(new PolicyDAO)) class PolicyDAO extends CRUDActor[Policy,Long] { ... } } 我想我遇到了跨多个scala测试用例共享ActorSystemConfig的问题.例如,ActorSystemConfig在PolicyDAOSystemTest和PolicyHolderDAOSystemTest中共享.我认为这是导致Akka抛出IllegalStateException的原因.这场冲突究竟发生在哪里?每次我调用policyDAOActor时都应该收到一个新演员,因为它正在通过system.actorOf,对吗? 感谢您的见解. 解决方法
此异常通常是actorSystem.shutdown的结果:
scala> val actorSystem: ActorSystem = ActorSystem("My-Actor-System") actorSystem: akka.actor.ActorSystem = akka://My-Actor-System scala> class Aaa extends Actor{ def receive = { case _ => }} defined class Aaa scala> actorSystem.actorOf(Props(new Aaa)) res178: akka.actor.ActorRef = Actor[akka://My-Actor-System/user/$a#-842131493] scala> actorSystem.shutdown scala> actorSystem.actorOf(Props(new Aaa)) java.lang.IllegalStateException: cannot create children while terminating or terminated at akka.actor.dungeon.Children$class.makeChild(Children.scala:200) at akka.actor.dungeon.Children$class.attachChild(Children.scala:40) at akka.actor.ActorCell.attachChild(ActorCell.scala:369) at akka.actor.ActorSystemImpl.actorOf(ActorSystem.scala:554) ... 43 elided 正如您在默认情况下在许多测试之间共享ActorSystem的一个实例一样 – 它们中的一个可能显式或隐式地关闭(例如在after之后甚至afterAll之后).此外,您在此创建了两个具有相同名称的actor系统 – 一个来自(actorSystemConfig:ActorSystemConfig),第二个来自 – 使用ActorSystemConfig(请参阅PolicyDAOSystemTest).默认情况下,第一个在应用程序的所有测试之间共享. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |