Sebastien Lorber
Sebastien Lorber

Reputation: 92180

Play2 Scala - Global cannot be cast to play.GlobalSettings

I've tried to create a Global object in app/Global.scala to run an Akka scheduler, like some other SO post was saying.

My code is nearly a copy/paste of the Global object tutorial, but on startup I get the following error:

Oops, cannot start the server.
PlayException: Cannot init the Global object [Global cannot be cast to play.GlobalSettings]
    at play.api.PlayException$.apply(Exceptions.scala:122)
    at play.api.Application$$anonfun$3.apply(Application.scala:71)
    at play.api.Application$$anonfun$3.apply(Application.scala:67)
    at play.utils.Threads$.withContextClassLoader(Threads.scala:17)
    at play.api.Application.<init>(Application.scala:66)
    at play.core.StaticApplication.<init>(ApplicationProvider.scala:49)
    at play.core.server.NettyServer$.createServer(NettyServer.scala:132)
    at play.core.server.NettyServer$$anonfun$main$5.apply(NettyServer.scala:153)
    at play.core.server.NettyServer$$anonfun$main$5.apply(NettyServer.scala:152)
    at scala.Option.map(Option.scala:133)
    at play.core.server.NettyServer$.main(NettyServer.scala:152)
    at play.core.server.NettyServer.main(NettyServer.scala)
Caused by: java.lang.ClassCastException: Global cannot be cast to play.GlobalSettings
    at play.api.Application.liftedTree1$1(Application.scala:44)
    at play.api.Application.play$api$Application$$javaGlobal(Application.scala:43)
    at play.api.Application$$anonfun$3.apply(Application.scala:68)
    ... 10 more

Here's my code:

import play.api._
import play.api.Play.current
import akka.util.duration._
import play.api.libs.concurrent._

/**
 * @author Sebastien Lorber (<i>[email protected]</i>)
 * Date: 21/11/12 - Time: 21:55
 */
class Global extends GlobalSettings {

  override def onStart(app: Application) {
    Logger.info("Application has started")
    startElasticSearchIndexationScheduling
  }

  override def onStop(app: Application) {
    Logger.info("Application shutdown...")
  }

  def startElasticSearchIndexationScheduling = {
    Akka.system.scheduler.schedule(5 seconds, 15 seconds) {
      Logger.info("Doing ElasticSearch reindexation (TODO: just testing scheduler")
    }
  }


}

Nothing fancy like you see...

By the way, I don't understand why there is often 2 different packages for objects of the same nameplay.GlobalSettings / play.api.GlobalSettings etc. One object seems to be for Java usage and the other for Scala, but the package name make this not very obvious. And I'm using Scala with a Scala global object importing "play.api.GlobalSettings" so why does it need to try to cast to play.GlobalSettings which seems more Java oriented (I tried extending this one and it doesn't work either, and it's not what the tutorial says)

Thanks

Upvotes: 3

Views: 3353

Answers (3)

Joseph Lust
Joseph Lust

Reputation: 19985

Make sure you're using play.api.GlobalSettings for Scala, not play.GlobalSettings which is the Java version. Otherwise you can get this class casting warning.

Upvotes: 1

mauhiz
mauhiz

Reputation: 501

If you happen to have a class with a companion object:

class Global extends WithFilters...

object Global extends Global

then it also fails at start time with the same error. The solution is to make the class abstract:

abstract class Global extends WithFilters...

This is because Play! first looks for a java Global, which is a class, before looking for a scala Global, which is an object.

Upvotes: 0

ndeverge
ndeverge

Reputation: 21564

You have to use an object, not a class with the Scala Global object:

...
object Global extends GlobalSettings {
...
}

Take a look at the Play documentation on Global object with Scala

About the play.* against play.api.*, it is sure that it is not obvious to make the difference. Let's just say that the Play's core is Scala (api), and the Java part is just a wrapper around it.

Upvotes: 10

Related Questions