How to get past SQLException: Attempting to obtain a connection from a pool that has already been shutdown

StackOverflow https://stackoverflow.com/questions/19283421

Question

I've got a Play (v 2.2.0) app using Typesafe Slick (v 1.0.1), and I'm trying to write a test (specs2) that seeds a PostgreSQL database, then makes a call to various controller actions to validate the existence of the data. In my test, I have:

 "Countries" should {
      "initialize" in {
        running(FakeApplication(additionalConfiguration = inMemoryDatabase())) {
          AppDB.database.withSession {
            implicit session: Session =>

              AppDB.dal.create
              AppDB.dal.seedForTests

              AppDB.dal.Countries.findAll().size must be_>=(1)
          }
        }
      }

by itself, this works fine. But, when I add another test action, like:

  "respond to Index()" in {
    val result = controllers.Countries.index()(FakeRequest())

    status(result) must equalTo(OK)
  }

my test fails with the message:

SQLException: Attempting to obtain a connection from a pool that has already been shutdown.

The relevant parts of the stacktrace are:

[error]     SQLException: Attempting to obtain a connection from a pool that has already been shutdown. 
[error] Stack trace of location where pool was shutdown follows:
[error]  java.lang.Thread.getStackTrace(Thread.java:1503)
[error]  com.jolbox.bonecp.BoneCP.captureStackTrace(BoneCP.java:559)
[error]  com.jolbox.bonecp.BoneCP.shutdown(BoneCP.java:161)
[error]  com.jolbox.bonecp.BoneCPDataSource.close(BoneCPDataSource.java:143)
[error]  play.api.db.BoneCPApi.shutdownPool(DB.scala:414)
[error]  play.api.db.BoneCPPlugin$$anonfun$onStop$1.apply(DB.scala:264)
[error]  play.api.db.BoneCPPlugin$$anonfun$onStop$1.apply(DB.scala:262)
[error]  scala.collection.immutable.List.foreach(List.scala:318)
[error]  play.api.db.BoneCPPlugin.onStop(DB.scala:262)
...

I've tried moving both the FakeApplication(...) and AppDB.database.withSession blocks higher in the code, as well as wrapping the val result = controllers.Countries.index(...) code in an AppDB.database.withSession wrapper, but still have had no luck.

Thank you for any direction.

Was it helpful?

Solution

You can use AroundExample to initialise your DB and run your tests:

class CountriesSpec extends mutable.Specification with AroundExample {

  def around[R : AsResult](r: =>R) = 
    running(FakeApplication(additionalConfiguration = inMemoryDatabase())) {
      AppDB.database.withSession { implicit session: Session =>
        AppDB.dal.create
        AppDB.dal.seedForTests
        AppDB.dal.Countries.findAll().size must be_>=(1)
        // just AsResult(r) with the latest 2.2.3 specs2 
        AsResult.effectively(r)
      }
    }

  "Countries" should {
    "respond to Index()" in {
      val result = controllers.Countries.index()(FakeRequest())
      status(result) must equalTo(OK)
    }
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top