2015-01-24 7 views
7

Qui è l'errore che sto ricevendo da Akka:Perché Akka non riesce con "IllegalStateException: impossibile creare figli mentre si termina o si termina" durante il test con ScalaTest?

[debug] Running TaskDef(com.suredbits.core.util.time.TimeUtilUnitTest, [email protected], false, [SuiteSelector]) 
[debug] Running TaskDef(com.suredbits.core.address.AddressDAOSystemTest, [email protected], false, [SuiteSelector]) 
[debug] Running TaskDef(com.suredbits.core.policy.PolicyHolderDAOUnitTest, [email protected], false, [SuiteSelector]) 
[debug] Running TaskDef(rpc.ModesTest, [email protected], false, [SuiteSelector]) 
[debug] Running TaskDef(com.suredbits.core.policy.PolicyDAOSystemTest, [email protected], false, [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, [email protected], false, [SuiteSelector]) 
[debug] Running TaskDef(com.suredbits.core.CurrencyUnitsTest, [email protected], false, [SuiteSelector]) 
[debug] Running TaskDef(com.suredbits.core.AddressMonitorUnitTest, [email protected], false, [SuiteSelector]) 
[debug] Running TaskDef(com.suredbits.core.blockexplorer.BlockCypherSvcUnitTest, [email protected], false, [SuiteSelector]) 
[debug] Running TaskDef(com.suredbits.core.address.AddressDAOUnitTest, [email protected], false, [SuiteSelector]) 
[debug] Running TaskDef(com.suredbits.core.protocol.BitcoinAddressTest, [email protected], false, [SuiteSelector]) 
[debug] Running TaskDef(com.suredbits.core.blockexplorer.BlockchainInfoSvcUnitTest, [email protected], false, [SuiteSelector]) 

Qui è il banco di prova che sto cercando di eseguire:

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) 
} 

Ecco il codice Scala per ActorSystemConfig

trait ActorSystemConfig { 
    val actorSystem: ActorSystem = ActorSystem("My-Actor-System") 
    implicit val timeout = Timeout(2 seconds) 
} 


object ActorSystemConfig extends ActorSystemConfig 

Infine, ecco il mio codice sorgente per 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] { 
    ... 
     } 
    } 

penso Sono in esecuzione in problemi di condivisione ActorSystemConfig su più casi di test Scala. Ad esempio, ActorSystemConfig è condiviso in PolicyDAOSystemTest e PolicyHolderDAOSystemTest. Sto pensando che questo è ciò che sta causando ad Akka di lanciare il IllegalStateException. Ma dove si trova esattamente questo conflitto? Dovrei ricevere un nuovo attore ogni volta che chiamo policyDAOActor dal momento che sta passando per system.actorOf, corretto?

Grazie per l'intuizione.

+0

Non so se è correlato, ma qui hai creato due sistemi di attori con lo stesso nome - uno da '(actorSystemConfig: ActorSystemConfig)', il secondo da - 'con ActorSystemConfig'. Posso scommettere che stai chiamando shutdown su 'ActorSystemConfig.actorSystem' da qualche parte. – dk14

risposta

10

Questa eccezione è di solito una conseguenza di 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 

Come stai condividendo un'istanza di ActorSystem tra molte prove di default - è possibile che uno di loro ha fatto l'arresto esplicitamente o implicitamente (ad esempio all'interno di after o anche afterAll). Inoltre, hai creato due sistemi di attori con lo stesso nome qui: uno da (actorSystemConfig: ActorSystemConfig), il secondo da - with ActorSystemConfig (vedi PolicyDAOSystemTest). Il primo è condiviso tra tutti i test dell'applicazione per impostazione predefinita.

+0

Puoi approfondire un po 'come "il primo è condiviso di default". È a causa di 'TestKit'? –

+1

No, a causa di un oggetto 'globale ActorSystemConfig estende ActorSystemConfig' – dk14

+0

lo si utilizza all'interno di' PolicyDAOSystemTest', in realtà questa eccezione si è verificata durante l'inizializzazione di questo test – dk14

Problemi correlati