Upgrading to Play 2.5.18 from 2.5.12 MailerClient causing ProvisionException: Unable to provision No implementation for play.libs.mailer.MailerClient was bound


(Dan Zeller) #1

I am moving my Play Framework application from 2.5.12 to 2.5.18. I get a clean and compile to process without errors, however, when I run the app, I receive this error:

ProvisionException: Unable to provision, see the following errors:

1) No implementation for play.libs.mailer.MailerClient was bound.
  while locating play.libs.mailer.MailerClient
    for field at controllers.AdultPTPController.mailerClient(AdultPTPController.java:105)
  while locating controllers.AdultPTPController
    for the 5th parameter of router.Routes.<init>(Routes.scala:67)
  while locating router.Routes
  while locating play.api.inject.RoutesProvider
  while locating play.api.routing.Router
    for the 1st parameter of play.api.http.JavaCompatibleHttpRequestHandler.<init>(HttpRequestHandler.scala:222)
  while locating play.api.http.JavaCompatibleHttpRequestHandler
  while locating play.api.http.HttpRequestHandler
    for the 6th parameter of play.api.DefaultApplication.<init>(Application.scala:236)
  at play.api.DefaultApplication.class(Application.scala:235)
  while locating play.api.DefaultApplication
  while locating play.api.Application

2) No implementation for play.libs.mailer.MailerClient was bound.
  while locating play.libs.mailer.MailerClient
    for field at controllers.Application.mailerClient(Application.java:63)
  while locating controllers.Application
    for the 3rd parameter of router.Routes.<init>(Routes.scala:67)
  while locating router.Routes
  while locating play.api.inject.RoutesProvider
  while locating play.api.routing.Router
    for the 1st parameter of play.api.http.JavaCompatibleHttpRequestHandler.<init>(HttpRequestHandler.scala:222)
  while locating play.api.http.JavaCompatibleHttpRequestHandler
  while locating play.api.http.HttpRequestHandler
    for the 6th parameter of play.api.DefaultApplication.<init>(Application.scala:236)
  at play.api.DefaultApplication.class(Application.scala:235)
  while locating play.api.DefaultApplication
  while locating play.api.Application

3) No implementation for play.libs.mailer.MailerClient was bound.
  while locating play.libs.mailer.MailerClient
    for field at controllers.account.Reset.mailerClient(Reset.java:45)
  while locating controllers.account.Reset
    for the 10th parameter of router.Routes.<init>(Routes.scala:67)
  while locating router.Routes
  while locating play.api.inject.RoutesProvider
  while locating play.api.routing.Router
    for the 1st parameter of play.api.http.JavaCompatibleHttpRequestHandler.<init>(HttpRequestHandler.scala:222)
  while locating play.api.http.JavaCompatibleHttpRequestHandler
  while locating play.api.http.HttpRequestHandler
    for the 6th parameter of play.api.DefaultApplication.<init>(Application.scala:236)
  at play.api.DefaultApplication.class(Application.scala:235)
  while locating play.api.DefaultApplication
  while locating play.api.Application

4) No implementation for play.libs.mailer.MailerClient was bound.
  while locating play.libs.mailer.MailerClient
    for field at controllers.account.Signup.mailerClient(Signup.java:52)
  while locating controllers.account.Signup
    for the 7th parameter of router.Routes.<init>(Routes.scala:67)
  while locating router.Routes
  while locating play.api.inject.RoutesProvider
  while locating play.api.routing.Router
    for the 1st parameter of play.api.http.JavaCompatibleHttpRequestHandler.<init>(HttpRequestHandler.scala:222)
  while locating play.api.http.JavaCompatibleHttpRequestHandler
  while locating play.api.http.HttpRequestHandler
    for the 6th parameter of play.api.DefaultApplication.<init>(Application.scala:236)
  at play.api.DefaultApplication.class(Application.scala:235)
  while locating play.api.DefaultApplication
  while locating play.api.Application

4 errors
No source available, here is the exception stack trace:
->com.google.inject.ProvisionException: Unable to provision, see the following errors:
     com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1028)
     com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1054)
     play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:405)
     play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:400)
     play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:137)
     play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21)
     play.core.server.DevServerStart$$anon$1.$anonfun$get$6(DevServerStart.scala:171)
     play.utils.Threads$.withContextClassLoader(Threads.scala:21)
     play.core.server.DevServerStart$$anon$1.$anonfun$get$3(DevServerStart.scala:168)
     scala.Option.map(Option.scala:146)
     play.core.server.DevServerStart$$anon$1.$anonfun$get$2(DevServerStart.scala:133)
     scala.util.Success.flatMap(Try.scala:247)
     play.core.server.DevServerStart$$anon$1.$anonfun$get$1(DevServerStart.scala:131)
     scala.concurrent.Future$.$anonfun$apply$1(Future.scala:655)
     scala.util.Success.$anonfun$map$1(Try.scala:251)
     scala.util.Success.map(Try.scala:209)
     scala.concurrent.Future.$anonfun$map$1(Future.scala:289)
     scala.concurrent.impl.Promise.liftedTree1$1(Promise.scala:29)
     scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:29)
     scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
     scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask.exec(ExecutionContextImpl.scala:140)
     java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
     java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
     java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
     java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

Here some code from the Application.java:

import java.awt.Desktop;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import javax.inject.Inject;

import org.apache.commons.mail.EmailException;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import controllers.AdultPTPController.AdultPTPForm;
import controllers.helpers.AccessMiddleware;
import managers.SessionData;
import models.AdultPTP;
import models.AdultPTPAudit;
import models.AdultPTPDemographic;
import models.AuditLog;
import models.Comment;
import models.DueDateNotice;
import models.Lookup;
import models.Provider;
import models.User;
import models.enums.RecordType;
import models.enums.RoleType;
import models.utils.AppException;
import models.utils.Mail;
import play.Logger;
import static play.data.Form.*;
import play.data.validation.Constraints;
import play.data.validation.ValidationError;
import play.i18n.Lang;
import play.i18n.Messages;
import play.i18n.MessagesApi;
import play.libs.mailer.MailerClient;
import play.mvc.BodyParser;
import play.mvc.Controller;
import play.mvc.Http;
import play.mvc.Http.Context;
import play.mvc.Http.RequestBody;
import play.mvc.Result;
import views.html.*;
import views.html.ptpAdultForm.*;
import views.html.admin.*;
import play.data.Form;
import play.data.FormFactory;

/**
 * @author Dan Zeller
 *
 */

public class Application extends Controller {
	
	@Inject
	MailerClient mailerClient;
	
	@Inject
	FormFactory formFactory;

    @Inject
    static MessagesApi messagesApi;
    
    static Collection<Lang> candidates = Collections.singletonList(new Lang(Locale.US));
    static Messages messages = messagesApi.preferred(candidates);
    ...............
}

Line 63 is:
public class Application extends Controller {

I am have read that I need some sort of Java Provider to correct this. I have never written anything like this and not sure how to correct this problem. Examples on how to do this would be great.


(Marcos Pereira) #2

Have you also updated play-mailer?


(Greg Methvin) #3

Did you provide the bindings required here? https://github.com/playframework/play-mailer#play-25x-and-java


(Dan Zeller) #4

I am using the 6.0.1 version.

In my build.sbt file:
"com.typesafe.play" %% "play-mailer" % "6.0.1"


(Dan Zeller) #5

Yes - I saw that and I added a module and a provider in my app.

Module:

package modules;

import com.google.inject.AbstractModule;
import com.typesafe.config.Config;

public class ConfigModule extends AbstractModule {
  @Override
  protected void configure() {
    bind(Config.class).toProvider(providers.ConfigProvider.class);
  }
}

Provider:

package providers;

import com.typesafe.config.Config;
import play.Configuration;

import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;

@Singleton
public class ConfigProvider implements Provider<Config> {

  private final Configuration configuration;

  @Inject
  public ConfigProvider(Configuration configuration) {
    this.configuration = configuration;
  }

  @Override
  public Config get() {
    return this.configuration.underlying();
  }

}

I also added this to my application.conf file:
playmodules.enabled += "modules.ConfigModule"

But with all this, I still get that error.


(Rich Dougherty) #6

Are you including play-mailer-guice which is where the bindings are defined?

libraryDependencies += "com.typesafe.play" %% "play-mailer-guice" % "6.0.1"

(Greg Methvin) #7

That should be

play.modules.enabled += "modules.ConfigModule"

But yeah, looking at the error, it seems the problem is you don’t have the MailerClient binding. If you add the play-mailer-guice library like @richdougherty suggested you should get it automatically:


(Dan Zeller) #8

Thanks Rich - that seem to fix the issue. However, I am now receiving a new error, which I am not sure about it also. I will create a new thread for this since this is a different issue.


(Dan Zeller) #9

Thanks Greg - I didn’t catch that mistake. Rich’s solution corrected the issue, but a new error has popped up, which I will create a new thread.