inject one singleton actor in multiple controllers

233 views
Skip to first unread message

ido

unread,
Jun 5, 2016, 3:03:15 PM6/5/16
to play-framework
Hi,
I try to inject one actor in 2 controllers, but on startup this fails.
I need this actor to be a singleton.

How should I do this?

class BetterModule extends AbstractModule with AkkaGuiceSupport {
  def configure = {
    bindActor[MailerActor]("mailer")
  }
}

@Singleton
class Users @Inject()(configuration: Configuration, @Named("mailer") mailer: ActorRef) extends Controller with Security with I18nSupport {

}

@Singleton
class Mail @Inject()(override val cache: CacheApi, @Named("mailer") mailer: ActorRef) extends Controller with Security {

}


thank you very much,
ido


play.api.UnexpectedException: Unexpected exception[ProvisionException: Unable to provision, see the following errors:

1) Error injecting constructor, java.util.concurrent.TimeoutException: Futures timed out after [1 second]
  at controllers.Application.<init>(Application.scala:164)
  at controllers.Application.class(Application.scala:140)
  while locating controllers.Application
    for parameter 1 at router.Routes.<init>(Routes.scala:75)
  while locating router.Routes
  while locating play.api.inject.RoutesProvider
  while locating play.api.routing.Router
    for parameter 0 at play.api.http.JavaCompatibleHttpRequestHandler.<init>(HttpRequestHandler.scala:200)
  while locating play.api.http.JavaCompatibleHttpRequestHandler
  while locating play.api.http.HttpRequestHandler
    for parameter 4 at play.api.DefaultApplication.<init>(Application.scala:221)
  at play.api.DefaultApplication.class(Application.scala:221)
  while locating play.api.DefaultApplication
  while locating play.api.Application

1 error]
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:170)
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:126)
    at scala.Option.map(Option.scala:146)
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1.apply(DevServerStart.scala:126)
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1.apply(DevServerStart.scala:124)
    at scala.util.Success.flatMap(Try.scala:231)
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:124)
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:116)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
Caused by: com.google.inject.ProvisionException: Unable to provision, see the following errors:

1) Error injecting constructor, java.util.concurrent.TimeoutException: Futures timed out after [1 second]
  at controllers.Application.<init>(Application.scala:164)
  at controllers.Application.class(Application.scala:140)
  while locating controllers.Application
    for parameter 1 at router.Routes.<init>(Routes.scala:75)
  while locating router.Routes
  while locating play.api.inject.RoutesProvider
  while locating play.api.routing.Router
    for parameter 0 at play.api.http.JavaCompatibleHttpRequestHandler.<init>(HttpRequestHandler.scala:200)
  while locating play.api.http.JavaCompatibleHttpRequestHandler
  while locating play.api.http.HttpRequestHandler
    for parameter 4 at play.api.DefaultApplication.<init>(Application.scala:221)
  at play.api.DefaultApplication.class(Application.scala:221)
  while locating play.api.DefaultApplication
  while locating play.api.Application

1 error
    at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1025)
    at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1051)
    at play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:405)
    at play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:400)
    at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:123)
    at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21)
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1$$anonfun$2.apply(DevServerStart.scala:158)
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1$$anonfun$2.apply(DevServerStart.scala:155)
    at play.utils.Threads$.withContextClassLoader(Threads.scala:21)
    at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:155)
Caused by: java.util.concurrent.TimeoutException: Futures timed out after [1 second]
    at scala.concurrent.impl.Promise$DefaultPromise.ready(Promise.scala:219)
    at scala.concurrent.impl.Promise$DefaultPromise.result(Promise.scala:223)
    at scala.concurrent.Await$$anonfun$result$1.apply(package.scala:190)
    at scala.concurrent.BlockContext$DefaultBlockContext$.blockOn(BlockContext.scala:53)
    at scala.concurrent.Await$.result(package.scala:190)
    at controllers.InitialData.insert(InitialData.scala:172)
    at controllers.Application.onStart(Application.scala:363)
    at controllers.Application.<init>(Application.scala:355)
    at controllers.Application.<init>(Application.scala:164)
    at controllers.Application$$FastClassByGuice$$b5b6aa19.newInstance(<generated>)

Will Sargent

unread,
Jun 6, 2016, 1:32:07 PM6/6/16
to play-framework
You show controllers.Mail and controllers.User, but the error is in controllers.Application, which is not listed.  Have you checked that your parameters to Application are good?

  at controllers.Application.<init>(Application.scala:164)
  at controllers.Application.class(Application.scala:140)
  while locating controllers.Application

Will.

ido

unread,
Jun 6, 2016, 4:45:31 PM6/6/16
to play-framework
So it should work this way? This is the info I need, then I can start debugging...

The app starts normally. But as soon as I uncomment any of the injected mailer actors in more than one controller I get this error.
In this case it was in the controllers.Mail, not in controllers.Application. There I also tried it once.
Sorry, but I cant reduce it to a reproducible example, the actual signatures of everything are of course more complicated.


thank you very much,
ido


@Singleton
class Application(env: Environment,
                  gulpAssets: GulpAssets,
                  lifecycle: ApplicationLifecycle,
                  dbConfigProvider: DatabaseConfigProvider,
                  override val betterDb: BetterDb,
                  val messagesApi: MessagesApi,
                  val cache: CacheApi,
                  configuration: Configuration,
                  system: ActorSystem,
          //        @Named("mailer") mailer: ActorRef,
                  router: => Option[Router] = None) extends Controller with Security with I18nSupport {

  // Router needs to be wrapped by Provider to avoid circular dependency when doing DI
  @Inject
  def this(env: Environment, gulpAssets: GulpAssets,
            lifecycle: ApplicationLifecycle,
            dbConfigProvider: DatabaseConfigProvider,
            betterDb: BetterDb,
            messagesApi: MessagesApi,
            cache: CacheApi,
            configuration: Configuration,
       //     mailer: ActorRef,
            system: ActorSystem,
            router: Provider[Router]) =
    this(env, gulpAssets, lifecycle,
           dbConfigProvider, betterDb,
          messagesApi, cache, configuration, system, Some(router.get))
Reply all
Reply to author
Forward
0 new messages