8
votes

In a Scala-based Play application, I'm trying to initiate a singleton service without requiring a request to a controller. I've followed the directions in the 2.4 API documentation to create a singleton class and then use Guice's dependency injection library to bind the class as an eager singleton.

Even with eager binding, the singleton still doesn't get called until after I've received a request through a controller route. Any ideas as to what I'm doing wrong?

Module

package models

import com.google.inject.AbstractModule
import com.google.inject.name.Names

class MessageLogModule extends AbstractModule {
  def configure() = {
    bind(classOf[MessageLogService]).asEagerSingleton
  }
}

Configuration

play.modules.enabled += "models.MessageLogModule"

Singleton

package models

import javax.inject._

@Singleton
class MessageLogService {
  // Create a file to test
  println("IN SINGLETON - CREATING NEW FILE")
  val file = new java.io.File("howdy.txt")
  file.createNewFile
}

Run Command

sbt compile run

The above singleton does not get called until I issue a...

curl http://localhost:9000/

What I want is for MessageLogService to start at the point of running the service and not wait for a request to hit a controller route.

1
Did you try "sbt compile start"? Run does some tricks during development. - Alvaro Carrasco
@AlvaroCarrasco Awesome! That was it! Can you post that as an official answer so I can make it as 'Answered' and give you the credit? - Jordan Parmer
For anyone else who runs across this, here is a post that discusses the differences between run and start: stackoverflow.com/questions/18213427/… - Jordan Parmer

1 Answers

11
votes

What you want is: sbt compile start

run delays compilation and initialization until first request to allow for faster change-refresh-see-change development cycle.