angelokh
angelokh

Reputation: 9428

Play 2.2 tests failed with exception 'The play Cache is not alive (STATUS_SHUTDOWN)'

When I run my tests, this error throws out immediately after 1st test. I guess it is because Play is using CacheManager.create(ehcacheXml) which only creates one instance per application.

[error]     IllegalStateException: The play Cache is not alive (STATUS_SHUTDOWN) (Cache.java:4267)

How to configure play to use multi-instances ehcache?

Here is my test:

abstract class WithCleanTestData extends WithApplication(FakeApplication(
  additionalConfiguration = TestConf.getConf.toMap
  )) {
  override def around[T: AsResult](t: => T): Result = super.around {
    prepareDbWithData()
    t
  }
  def prepareDbWithData() = {
  }
}

object MyTest extends PlaySpecification {

  "test api" should {
    class MyCtrl() extends Controller with MyControler

    "post data 1" in new WithCleanTestData {
      val myControler = new MyCtrl()
      val ret: Future[SimpleResult] = myControler.method().apply(FakeRequest())
      .....
    }

    "post data 2" in new WithCleanTestData {
      val myControler = new MyCtrl()
      val ret: Future[SimpleResult] = myControler.method().apply(FakeRequest())
      .....
    }
  }
}

Upvotes: 0

Views: 3350

Answers (2)

johanandren
johanandren

Reputation: 11479

See my reply on the play mailing list!

https://groups.google.com/d/topic/play-framework/PBIfeiwl5rU/discussion


/**
 * Custom in-memory cache plugin working around the shortcomings of the play bundled one.
 *
 * See more:
 * https://groups.google.com/d/msg/play-framework/PBIfeiwl5rU/-IWifSWhBlAJ
 *
 */
class FixedEhCachePlugin(app: Application) extends CachePlugin {

  lazy val cache = {
    val manager = CacheManager.getInstance()
    manager.addCacheIfAbsent("play")
    manager.getCache("play")
  }

  override def onStart() {
    cache
  }

  override def onStop() {
    cache.flush()
  }

  lazy val api = new CacheAPI {

    def set(key: String, value: Any, expiration: Int) {
      val element = new Element(key, value)
      if (expiration == 0) element.setEternal(true)
      element.setTimeToLive(expiration)
      cache.put(element)
    }

    def get(key: String): Option[Any] = {
      Option(cache.get(key)).map(_.getObjectValue)
    }

    def remove(key: String) {
      cache.remove(key)
    }
  }

}

Upvotes: 4

nylund
nylund

Reputation: 1105

Based on johanandren's post I made this work around for Java,

play.Play.application().plugin(EhCachePlugin.class).cache().flush();

This is added in our test base class in @After.

Upvotes: 0

Related Questions