Search code examples
scalaplayframeworkguice

Unable to provision because of "No implementation for controllers.MyExecutionContext was bound"


I'm trying to follow the instructions to create a Play Framework async controller. So far my code is little more than a cut & paste from the Play documentation:

package controllers

import akka.actor.ActorSystem
import com.google.inject.Inject
import play.api.libs.concurrent.CustomExecutionContext
import play.api.mvc.{AbstractController, ControllerComponents}
import scala.concurrent.{ExecutionContext, Future}
trait MyExecutionContext extends ExecutionContext

class MyExecutionContextImpl @Inject()(system: ActorSystem)
  extends CustomExecutionContext(system, "my.executor") with MyExecutionContext

class FooController @Inject() (myExecutionContext: MyExecutionContext, cc:ControllerComponents) extends AbstractController(cc) {
  def foo = Action.async(
    Future {
      // Call some blocking API
      Ok("result of blocking call")
    }(myExecutionContext)

  )
}

When I try to run this new controller, I get the following error:

ProvisionException: Unable to provision, see the following errors:

1) No implementation for controllers.MyExecutionContext was bound.
  while locating controllers.MyExecutionContext
    for the 1st parameter of controllers.FooController.<init>(FooController.scala:14)
  while locating controllers.FooController
    for the 4th parameter of router.Routes.<init>(Routes.scala:33)
  while locating router.Routes
  while locating play.api.inject.RoutesProvider

Can anybody explain what might be going wrong here?


Solution

  • The exception indicates that you have not bound the implementation (MyExecutionContext) to the trait (MyExecutionContextImpl) in your Module.

    Try this:

    class Module extends AbstractModule {
    
      override def configure(): Unit = {
        bind(classOf[MyExecutionContext])
          .to(classOf[MyExecutionContextImpl])
    
      }
    }
    

    However I never used your approach. I use only the default Execution Context like:

    class FooController @Inject()()(implicit val ec: ExecutionContext)