diff --git a/app/annotations/CommuteEbeanServer.java b/app/annotations/CommuteEbeanServer.java new file mode 100644 index 0000000..014b0ec --- /dev/null +++ b/app/annotations/CommuteEbeanServer.java @@ -0,0 +1,12 @@ +package annotations; + +import com.google.inject.BindingAnnotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@BindingAnnotation +@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD, ElementType.CONSTRUCTOR }) @Retention(RetentionPolicy.RUNTIME) +public @interface CommuteEbeanServer {} \ No newline at end of file diff --git a/app/controllers/SignupController.java b/app/controllers/SignupController.java index 1726688..730baa0 100644 --- a/app/controllers/SignupController.java +++ b/app/controllers/SignupController.java @@ -1,5 +1,6 @@ package controllers; +import annotations.CommuteEbeanServer; import com.google.inject.Inject; import enums.pushservices.PlatformType; import helpers.ValidationHelper; @@ -31,7 +32,7 @@ public class SignupController extends Controller { private FormFactory mFormFactory; @Inject - public SignupController(EbeanServer ebeanServer, FormFactory formFactory) { + public SignupController(@CommuteEbeanServer EbeanServer ebeanServer, FormFactory formFactory) { mEbeanServer = ebeanServer; mFormFactory = formFactory; } diff --git a/app/dao/AccountDao.java b/app/dao/AccountDao.java index 59f3c2f..245fbe7 100644 --- a/app/dao/AccountDao.java +++ b/app/dao/AccountDao.java @@ -1,5 +1,6 @@ package dao; +import annotations.CommuteEbeanServer; import enums.pushservices.PlatformType; import io.ebean.EbeanServer; import io.ebean.FetchConfig; @@ -21,7 +22,7 @@ public class AccountDao extends BaseDao { @Inject - public AccountDao(EbeanServer ebeanServer) { + public AccountDao(@CommuteEbeanServer EbeanServer ebeanServer) { super(ebeanServer); } diff --git a/app/dao/AgencyDao.java b/app/dao/AgencyDao.java index 9fb78f3..c8d6252 100644 --- a/app/dao/AgencyDao.java +++ b/app/dao/AgencyDao.java @@ -1,5 +1,6 @@ package dao; +import annotations.CommuteEbeanServer; import io.ebean.EbeanServer; import io.ebean.FetchConfig; import io.ebean.OrderBy; @@ -22,7 +23,7 @@ public class AgencyDao extends BaseDao { @Inject - public AgencyDao(EbeanServer ebeanServer) { + public AgencyDao(@CommuteEbeanServer EbeanServer ebeanServer) { super(ebeanServer); } diff --git a/app/dao/BaseDao.java b/app/dao/BaseDao.java index 8d2e293..79ce0b6 100644 --- a/app/dao/BaseDao.java +++ b/app/dao/BaseDao.java @@ -1,5 +1,6 @@ package dao; +import annotations.CommuteEbeanServer; import io.ebean.EbeanServer; import io.ebean.config.ServerConfig; import io.ebeaninternal.api.SpiEbeanServer; @@ -14,7 +15,7 @@ class BaseDao { EbeanServer mEbeanServer; - BaseDao(EbeanServer ebeanServer) { + BaseDao(@CommuteEbeanServer EbeanServer ebeanServer) { mEbeanServer = ebeanServer; } diff --git a/app/dao/DeviceDao.java b/app/dao/DeviceDao.java index 2a64d63..f06bc90 100644 --- a/app/dao/DeviceDao.java +++ b/app/dao/DeviceDao.java @@ -1,5 +1,6 @@ package dao; +import annotations.CommuteEbeanServer; import io.ebean.EbeanServer; import io.ebean.OrderBy; import models.devices.Device; @@ -19,7 +20,7 @@ public class DeviceDao extends BaseDao { @Inject - public DeviceDao(EbeanServer ebeanServer) { + public DeviceDao(@CommuteEbeanServer EbeanServer ebeanServer) { super(ebeanServer); } diff --git a/app/injection/modules/DatabaseModule.java b/app/injection/modules/DatabaseModule.java index e0bda46..563863e 100644 --- a/app/injection/modules/DatabaseModule.java +++ b/app/injection/modules/DatabaseModule.java @@ -1,5 +1,6 @@ package injection.modules; +import annotations.CommuteEbeanServer; import com.google.inject.AbstractModule; import injection.providers.CommuteEbeanServerProvider; import io.ebean.EbeanServer; @@ -12,6 +13,7 @@ public class DatabaseModule extends AbstractModule { @Override protected void configure() { bind(EbeanServer.class) + .annotatedWith(CommuteEbeanServer.class) .toProvider(CommuteEbeanServerProvider.class) .asEagerSingleton(); } diff --git a/app/injection/modules/SchedulersModule.java b/app/injection/modules/SchedulersModule.java index a83b218..e9e9e13 100644 --- a/app/injection/modules/SchedulersModule.java +++ b/app/injection/modules/SchedulersModule.java @@ -14,7 +14,6 @@ public class SchedulersModule extends AbstractModule implements AkkaGuiceSupport protected void configure() { bindActor(AgencyUpdateActor.class, AgencyUpdateActor.ACTOR_NAME); - bind(CommuteSchedulers.class) - .asEagerSingleton(); + bind(CommuteSchedulers.class).asEagerSingleton(); } } \ No newline at end of file diff --git a/app/injection/providers/CommuteEbeanServerProvider.java b/app/injection/providers/CommuteEbeanServerProvider.java index 1457112..af1f8c8 100644 --- a/app/injection/providers/CommuteEbeanServerProvider.java +++ b/app/injection/providers/CommuteEbeanServerProvider.java @@ -5,6 +5,7 @@ import com.typesafe.config.Config; import com.typesafe.config.ConfigValue; import com.typesafe.config.ConfigValueType; +import io.ebean.Ebean; import io.ebean.EbeanServer; import io.ebean.EbeanServerFactory; import io.ebean.config.ServerConfig; @@ -17,6 +18,10 @@ import models.alerts.Route; import models.devices.Device; import models.devices.Subscription; +import play.Environment; +import play.db.DBApi; +import play.db.ebean.EbeanConfig; +import play.inject.ApplicationLifecycle; import java.util.ArrayList; import java.util.Map; @@ -28,10 +33,17 @@ * Copyright 4/2/16 Splendid Bits. */ public class CommuteEbeanServerProvider implements Provider { - private final EbeanServer mEbeanServer; + + private final Config config; @Inject - public CommuteEbeanServerProvider(Config config) { + public CommuteEbeanServerProvider(Config config, ServerConfig serverConfig, EbeanConfig ebeanConfig, + ApplicationLifecycle lifecycle, Environment environment, DBApi dbApi) { + this.config = config; + } + + @Override + public EbeanServer get() { if (config == null || config.isEmpty()) { throw new RuntimeException("No Play Framework configuration found."); } @@ -72,11 +84,8 @@ public CommuteEbeanServerProvider(Config config) { serverConfig.setDdlGenerate(false); serverConfig.setUpdateChangesOnly(false); - mEbeanServer = EbeanServerFactory.create(serverConfig); - } - - @Override - public EbeanServer get() { - return mEbeanServer; + EbeanServer ebeanServer = EbeanServerFactory.create(serverConfig); + Ebean.register(ebeanServer, true); + return ebeanServer; } } \ No newline at end of file diff --git a/app/main/LifecycleListener.java b/app/main/LifecycleListener.java index 979821a..a7eaecd 100644 --- a/app/main/LifecycleListener.java +++ b/app/main/LifecycleListener.java @@ -1,5 +1,6 @@ package main; +import annotations.CommuteEbeanServer; import com.google.inject.Inject; import com.google.inject.Singleton; import io.ebean.EbeanServer; @@ -11,7 +12,7 @@ public class LifecycleListener { @Inject - public LifecycleListener(EbeanServer ebeanServer, ApplicationLifecycle applicationLifecycle) { + public LifecycleListener(@CommuteEbeanServer EbeanServer ebeanServer, ApplicationLifecycle applicationLifecycle) { applicationLifecycle.addStopHook(() -> CompletableFuture.runAsync(() -> { ebeanServer.shutdown(true, false); })); diff --git a/build.sbt b/build.sbt index e20e6bc..4bf4e91 100644 --- a/build.sbt +++ b/build.sbt @@ -22,21 +22,13 @@ libraryDependencies ++= Seq( guice, "com.splendidbits" % "play-pushservices" % "1.1.2", "com.typesafe.play" %% "play-ahc-ws-standalone" % "1.0.1", - "com.typesafe.play" %% "play-ws-standalone-json" % "1.0.1", - "com.typesafe.play" %% "play-ws-standalone-xml" % "1.0.1", - "com.typesafe.play" %% "play-json" % "2.6.1", - "io.ebean" % "ebean-agent" % "10.1.6", "org.postgresql" % "postgresql" % "42.2.2", "org.jetbrains" % "annotations" % "13.0", - "org.jsoup" % "jsoup" % "1.10.1", "com.google.code.gson" % "gson" % "2.8.2", - "junit" % "junit" % "4.12" % Test, - "org.mockito" % "mockito-all" % "2.0.2-beta" % Test + "org.jsoup" % "jsoup" % "1.10.1", + "junit" % "junit" % "4.12" % Test ) -testOptions += Tests.Argument(TestFrameworks.JUnit, "-v", "-q") -//resolvers += ("Local Maven Repository" at "/Users/daniel/.ivy2/cache") - // Play provides two styles of routers, one expects its actions to be injected, the // other, legacy style, accesses its actions statically. routesGenerator := InjectedRoutesGenerator diff --git a/conf/application.conf b/conf/application.conf index ad64981..eb56b61 100644 --- a/conf/application.conf +++ b/conf/application.conf @@ -46,6 +46,11 @@ play.ws.ssl { } } +# To fix ebean / play injection race bug. +# https://github.com/playframework/playframework/issues/7017 +# https://github.com/playframework/play-ebean/issues/51 +//play.modules.disabled += "play.db.ebean.EbeanModule" + # !!! WARNING !! # EBeanORM Configuration # Postgresql Database Engine Configuration