Hi all,
Before Play 2.4, we had onStart in GlobalSetttings which allowed us to execute some code AFTER the application started.
Since Play 2.4 and the dependency injection orientation, it's recommended to for a class to perform its initialization in it's constructor. The eager binding works well when we want execute some code on start up without injecting the object anywhere, but it's happening before Application is really started.
Is there a way to do the same thing, but after the application started ? Some of the initialization I have in my case need the application to be started.
And I don't want to inject those objects in a controller, just to get the constructor called after the application started....
Thanks for your help
--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/55fb2ed3-bd05-48ad-b5ef-0653dd139e15%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
import javax.inject.Inject;
import akka.actor.ActorSystem;
class ExampleClass
{
@Inject
public ExampleClass(ActorSystem actorSystem)
{
actorSystem.actorOf(SomeActor.props());
}
}
- New instances are created every time a component is needed. If a component is used more than once, then, by default, multiple instances of the component will be created. If you only want a single instance of a component then you need to mark it as a singleton.
Please correct me if I'm wrong, but you need an entry point in which your dependencies will be injected. In Play the entry point is the controller instance which gets initialized if a route was requested on this controller. I cannot find any information regarding the lifecycle of a controller, so I assume that controllers are instantiated the same as all other dependency injected components. The documentation says:
- New instances are created every time a component is needed. If a component is used more than once, then, by default, multiple instances of the component will be created. If you only want a single instance of a component then you need to mark it as a singleton.
It sounds like that on every request a new controller instance will be created. This means also that my dependencies get injected on every request. As you can see this is not a viable option for an application wide startup hook, because it isn't guaranteed that my tasks get executed on application startup and it's also not guaranteed that it will be executed only once. Even if the controller will be instantiated once if an action will be called on it, then it isn't guaranteed that the controller will be ever issued.
import javax.inject.Inject;
import javax.inject.Singleton;
import akka.actor.ActorSystem;
@Singleton
class ExampleClass implements ExampleInterface
{
@Inject
public ExampleClass(ActorSystem actorSystem)
{
actorSystem.actorOf(SomeActor.props());
}
}
import javax.inject.Inject;import javax.inject.Singleton;
import akka.actor.ActorSystem;
@Singleton
class ExampleClass
{
@Inject
public ExampleClass(ActorSystem actorSystem)
{
actorSystem.actorOf(SomeActor.props());
}
}
import com.google.inject.AbstractModule;
class ExampleModule extends AbstractModule
{
@Override
protected void configure()
{
bind(ExampleInterface.class).to(ExampleClass.class).asEagerSingleton();
}
}
interface ExampleInterface {}
trait StartupClass {
def dummyCounter = 100
}
class StartupClassImpl extends StartupClass {
println("Eager Singleton Initialized during startup.. perform startup related tasks like Akka ActorSystem management etc....")
}
@RunWith(classOf[org.specs2.runner.JUnitRunner])
class StartupClassSpec extends PlaySpecification with Mockito with AkkaTestkitSpecs2Support {
sequential
"A Startup Class " should {
"must be available from Injector " in new MyContext {
new WithApplication(application) {
val m = application.injector
val y = application.injector.instanceOf[StartupClass]
y.dummyCounter mustEqual 100
}
}
}
trait MyContext extends TestContext {
val testModule = new AbstractModule with AkkaGuiceSupport {
def configure = {
bind(classOf[StartupClass]).to(classOf[StartupClassImpl]).asEagerSingleton();
}
}
/**
* The application.
*/
lazy val application = new GuiceApplicationBuilder()
.overrides(new FakeModule)
.overrides(testModule)
.build()
}
}
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
[info] p.a.l.c.ActorSystemProvider - Starting application default Akka system: application
Eager Singleton Initialized during startup.. perform startup related tasks like Akka ActorSystem management etc....
creating blogdaoactor
[info] p.a.l.c.ActorSystemProvider - Shutdown application default Akka system: application
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/1396cd94-7093-44b0-919a-abfc34a3a897%40googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/bbf589ff-967f-48ee-ba5f-2a4d0e0e8295%40googlegroups.com.
I have only one question. Is it possible to do something like "app.isTest()" in the old GlobalSettings file? Because many of these actors is not necessary when running the tests.
@Singletonpublic class OnStartClass implements OnStartInterface { private static Logger.ALogger logger = Logger.of(OnStartClass.class);
private ActorSystem actorSystem; private Configuration configuration; private JPAApi jpa;
@Inject public OnStartClass(ActorSystem actorSystem, Configuration configuration, Environment environment) { this.actorSystem = actorSystem; this.configuration = configuration; this.jpa = jpa; logger.info("Executing OnStartClass");
if(!environment.isTest()) { scheduleReports(); } }
private void reloadRemoveUnitActors() { ... empty for now }}
@Singletonpublic class OnStartClass implements OnStartInterface { private static Logger.ALogger logger = Logger.of(OnStartClass.class);
private ActorSystem actorSystem; private Configuration configuration; private JPAApi jpa;
/** * @param actorSystem the {@link akka.actor.ActorSystem} */ @Inject public OnStartClass(ActorSystem actorSystem, Configuration configuration, Environment environment, JPAApi jpa) {
this.actorSystem = actorSystem; this.configuration = configuration; this.jpa = jpa; logger.info("Executing OnStartClass");
if(!environment.isTest()) { scheduleReports(); } }
private void scheduleReports() { jpa.withTransaction(() -> { List<Unit> scheduledUnits = ReportsDAO.newInstance().all(); ... }); }}
! @6ml1ifk9l - Internal server error, for (GET) [/] -> play.api.UnexpectedException: Unexpected exception[CreationException: Unable to create injector, see the following errors:
1) Error injecting constructor, java.lang.ExceptionInInitializerError at play.db.jpa.DefaultJPAApi$JPAApiProvider.<init>(DefaultJPAApi.java:35) at play.db.jpa.DefaultJPAApi$JPAApiProvider.class(DefaultJPAApi.java:30) while locating play.db.jpa.DefaultJPAApi$JPAApiProvider while locating play.db.jpa.JPAApi for parameter 3 at actors.OnStartClass.<init>(OnStartClass.java:45) at actors.OnStartClass.class(OnStartClass.java:34) while locating actors.OnStartClass at modules.OnStartModule.configure(OnStartModule.java:15) (via modules: com.google.inject.util.Modules$OverrideModule -> modules.OnStartModule) while locating interfaces.OnStartInterface
1 error] at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:165) ~[play-server_2.11-2.4.2.jar:2.4.2] at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:121) ~[play-server_2.11-2.4.2.jar:2.4.2] at scala.Option.map(Option.scala:146) ~[scala-library-2.11.7.jar:na] at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1.apply(DevServerStart.scala:121) ~[play-server_2.11-2.4.2.jar:2.4.2] at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1.apply(DevServerStart.scala:119) ~[play-server_2.11-2.4.2.jar:2.4.2]Caused by: com.google.inject.CreationException: Unable to create injector, see the following errors:
1) Error injecting constructor, java.lang.ExceptionInInitializerError at play.db.jpa.DefaultJPAApi$JPAApiProvider.<init>(DefaultJPAApi.java:35) at play.db.jpa.DefaultJPAApi$JPAApiProvider.class(DefaultJPAApi.java:30) while locating play.db.jpa.DefaultJPAApi$JPAApiProvider while locating play.db.jpa.JPAApi for parameter 3 at actors.OnStartClass.<init>(OnStartClass.java:45) at actors.OnStartClass.class(OnStartClass.java:34) while locating actors.OnStartClass at modules.OnStartModule.configure(OnStartModule.java:15) (via modules: com.google.inject.util.Modules$OverrideModule -> modules.OnStartModule) while locating interfaces.OnStartInterface
1 error at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:466) ~[guice-4.0.jar:na] at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:184) ~[guice-4.0.jar:na] at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:110) ~[guice-4.0.jar:na] at com.google.inject.Guice.createInjector(Guice.java:96) ~[guice-4.0.jar:na] at com.google.inject.Guice.createInjector(Guice.java:73) ~[guice-4.0.jar:na]Caused by: java.lang.ExceptionInInitializerError: null at java.lang.Class.forName0(Native Method) ~[na:1.8.0_45] at java.lang.Class.forName(Class.java:348) ~[na:1.8.0_45] at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.classForName(ClassLoaderServiceImpl.java:242) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final] at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.buildHibernateConfiguration(EntityManagerFactoryBuilderImpl.java:1136) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final] at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:853) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]Caused by: java.lang.RuntimeException: There is no started application at scala.sys.package$.error(package.scala:27) ~[scala-library-2.11.7.jar:na] at play.api.Play$$anonfun$current$1.apply(Play.scala:71) ~[play_2.11-2.4.2.jar:2.4.2] at play.api.Play$$anonfun$current$1.apply(Play.scala:71) ~[play_2.11-2.4.2.jar:2.4.2] at scala.Option.getOrElse(Option.scala:121) ~[scala-library-2.11.7.jar:na] at play.api.Play$.current(Play.scala:71) ~[play_2.11-2.4.2.jar:2.4.2]2015-07-06 10:03:46,989 - [error] application -
Caused by: java.lang.RuntimeException: There is no started applicationat scala.sys.package$.error(package.scala:27) ~[scala-library-2.11.7.jar:na]at play.api.Play$$anonfun$current$1.apply(Play.scala:71) ~[play_2.11-2.4.2.jar:2.4.2]at play.api.Play$$anonfun$current$1.apply(Play.scala:71) ~[play_2.11-2.4.2.jar:2.4.2]at scala.Option.getOrElse(Option.scala:121) ~[scala-library-2.11.7.jar:na]at play.api.Play$.current(Play.scala:71) ~[play_2.11-2.4.2.jar:2.4.2]2015-07-06 10:03:46,989 - [error] application -
--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/2c372431-2bef-4c21-8588-52b94e63c567%40googlegroups.com.
! @6mlnb86mf - Internal server error, for (GET) [/] ->
play.api.UnexpectedException: Unexpected exception[CreationException: Unable to create injector, see the following errors:
1) Error injecting constructor, java.lang.ExceptionInInitializerError at play.db.jpa.DefaultJPAApi$JPAApiProvider.<init>(DefaultJPAApi.java:35) at play.db.jpa.DefaultJPAApi$JPAApiProvider.class(DefaultJPAApi.java:30) while locating play.db.jpa.DefaultJPAApi$JPAApiProvider while locating play.db.jpa.JPAApi for parameter 3 at actors.OnStartClass.<init>(OnStartClass.java:45) at actors.OnStartClass.class(OnStartClass.java:34) while locating actors.OnStartClass at modules.OnStartModule.configure(OnStartModule.java:15) (via modules: com.google.inject.util.Modules$OverrideModule -> modules.OnStartModule) while locating interfaces.OnStartInterface
1 error] at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:165) ~[play-server_2.11-2.4.2.jar:2.4.2] at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:121) ~[play-server_2.11-2.4.2.jar:2.4.2] at scala.Option.map(Option.scala:146) ~[scala-library-2.11.7.jar:na] at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1.apply(DevServerStart.scala:121) ~[play-server_2.11-2.4.2.jar:2.4.2] at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1.apply(DevServerStart.scala:119) ~[play-server_2.11-2.4.2.jar:2.4.2]
at scala.util.Success.flatMap(Try.scala:231) ~[scala-library-2.11.7.jar:na] at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:119) ~[play-server_2.11-2.4.2.jar:2.4.2] at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:111) ~[play-server_2.11-2.4.2.jar:2.4.2] at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24) ~[scala-library-2.11.7.jar:na] at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24) ~[scala-library-2.11.7.jar:na] at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402) ~[na:1.8.0_45] at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) ~[na:1.8.0_45] at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056) ~[na:1.8.0_45] at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1689) ~[na:1.8.0_45] at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157) ~[na:1.8.0_45]
Caused by: com.google.inject.CreationException: Unable to create injector, see the following errors:
1) Error injecting constructor, java.lang.ExceptionInInitializerError at play.db.jpa.DefaultJPAApi$JPAApiProvider.<init>(DefaultJPAApi.java:35) at play.db.jpa.DefaultJPAApi$JPAApiProvider.class(DefaultJPAApi.java:30) while locating play.db.jpa.DefaultJPAApi$JPAApiProvider while locating play.db.jpa.JPAApi for parameter 3 at actors.OnStartClass.<init>(OnStartClass.java:45) at actors.OnStartClass.class(OnStartClass.java:34) while locating actors.OnStartClass at modules.OnStartModule.configure(OnStartModule.java:15) (via modules: com.google.inject.util.Modules$OverrideModule -> modules.OnStartModule) while locating interfaces.OnStartInterface
1 error at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:466) ~[guice-4.0.jar:na] at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:184) ~[guice-4.0.jar:na] at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:110) ~[guice-4.0.jar:na] at com.google.inject.Guice.createInjector(Guice.java:96) ~[guice-4.0.jar:na] at com.google.inject.Guice.createInjector(Guice.java:73) ~[guice-4.0.jar:na]
at com.google.inject.Guice.createInjector(Guice.java:62) ~[guice-4.0.jar:na] at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:126) ~[play_2.11-2.4.2.jar:2.4.2] at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:93) ~[play_2.11-2.4.2.jar:2.4.2] at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21) ~[play_2.11-2.4.2.jar:2.4.2] at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1$$anonfun$2.apply(DevServerStart.scala:153) ~[play-server_2.11-2.4.2.jar:2.4.2] at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1$$anonfun$2.apply(DevServerStart.scala:150) ~[play-server_2.11-2.4.2.jar:2.4.2] at play.utils.Threads$.withContextClassLoader(Threads.scala:21) ~[play_2.11-2.4.2.jar:2.4.2] at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:150) ~[play-server_2.11-2.4.2.jar:2.4.2] ... 14 common frames omitted
Caused by: java.lang.ExceptionInInitializerError: null at java.lang.Class.forName0(Native Method) ~[na:1.8.0_45] at java.lang.Class.forName(Class.java:348) ~[na:1.8.0_45] at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.classForName(ClassLoaderServiceImpl.java:242) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final] at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.buildHibernateConfiguration(EntityManagerFactoryBuilderImpl.java:1136) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final] at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:853) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final] at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:425) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final] at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:849) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final] at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:75) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final] at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:54) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final] at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55) ~[hibernate-jpa-2.1-api-1.0.0.Final.jar:1.0.0.Final] at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39) ~[hibernate-jpa-2.1-api-1.0.0.Final.jar:1.0.0.Final] at play.db.jpa.DefaultJPAApi.start(DefaultJPAApi.java:56) ~[play-java-jpa_2.11-2.4.2.jar:2.4.2] at play.db.jpa.DefaultJPAApi$JPAApiProvider.<init>(DefaultJPAApi.java:42) ~[play-java-jpa_2.11-2.4.2.jar:2.4.2] at play.db.jpa.DefaultJPAApi$JPAApiProvider$$FastClassByGuice$$dcd4cdbd.newInstance(<generated>) ~[guice-4.0.jar:2.4.2] at com.google.inject.internal.cglib.reflect.$FastConstructor.newInstance(FastConstructor.java:40) ~[guice-4.0.jar:na] at com.google.inject.internal.DefaultConstructionProxyFactory$1.newInstance(DefaultConstructionProxyFactory.java:61) ~[guice-4.0.jar:na] at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:105) ~[guice-4.0.jar:na] at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:85) ~[guice-4.0.jar:na] at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:267) ~[guice-4.0.jar:na] at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46) ~[guice-4.0.jar:na] at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1103) ~[guice-4.0.jar:na] at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40) ~[guice-4.0.jar:na] at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:145) ~[guice-4.0.jar:na] at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:41) ~[guice-4.0.jar:na] at com.google.inject.internal.BoundProviderFactory.get(BoundProviderFactory.java:61) ~[guice-4.0.jar:na] at com.google.inject.internal.SingleParameterInjector.inject(SingleParameterInjector.java:38) ~[guice-4.0.jar:na] at com.google.inject.internal.SingleParameterInjector.getAll(SingleParameterInjector.java:62) ~[guice-4.0.jar:na] at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:104) ~[guice-4.0.jar:na] at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:85) ~[guice-4.0.jar:na] at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:267) ~[guice-4.0.jar:na] at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46) ~[guice-4.0.jar:na] at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1103) ~[guice-4.0.jar:na] at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40) ~[guice-4.0.jar:na] at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:145) ~[guice-4.0.jar:na] at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:41) ~[guice-4.0.jar:na] at com.google.inject.internal.FactoryProxy.get(FactoryProxy.java:56) ~[guice-4.0.jar:na] at com.google.inject.internal.ProviderToInternalFactoryAdapter$1.call(ProviderToInternalFactoryAdapter.java:46) ~[guice-4.0.jar:na] at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1103) ~[guice-4.0.jar:na] at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40) ~[guice-4.0.jar:na] at com.google.inject.internal.SingletonScope$1.get(SingletonScope.java:145) ~[guice-4.0.jar:na] at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:41) ~[guice-4.0.jar:na] at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:205) ~[guice-4.0.jar:na] at com.google.inject.internal.InternalInjectorCreator$1.call(InternalInjectorCreator.java:199) ~[guice-4.0.jar:na] at com.google.inject.internal.InjectorImpl.callInContext(InjectorImpl.java:1092) ~[guice-4.0.jar:na] at com.google.inject.internal.InternalInjectorCreator.loadEagerSingletons(InternalInjectorCreator.java:199) ~[guice-4.0.jar:na] at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:180) ~[guice-4.0.jar:na] ... 25 common frames omitted
Caused by: java.lang.RuntimeException: There is no started application at scala.sys.package$.error(package.scala:27) ~[scala-library-2.11.7.jar:na] at play.api.Play$$anonfun$current$1.apply(Play.scala:71) ~[play_2.11-2.4.2.jar:2.4.2] at play.api.Play$$anonfun$current$1.apply(Play.scala:71) ~[play_2.11-2.4.2.jar:2.4.2] at scala.Option.getOrElse(Option.scala:121) ~[scala-library-2.11.7.jar:na] at play.api.Play$.current(Play.scala:71) ~[play_2.11-2.4.2.jar:2.4.2]
at play.api.Play.current(Play.scala) ~[play_2.11-2.4.2.jar:2.4.2] at play.Play.application(Play.java:17) ~[play_2.11-2.4.2.jar:2.4.2] at models.file.Transcode.<clinit>(Transcode.java:34) ~[na:na] ... 72 common frames omitted
import akka.actor.Actor
import play.api.libs.concurrent.Akka
import scala.concurrent.duration._
import play.api.Play.current
import scala.concurrent.ExecutionContext.Implicits.global
class Scheduler extends Actor {
override def preStart() {
val dbupdate = Akka.system.scheduler.schedule(
0.microseconds, 5.minutes, self, "update")
val pictureClean = Akka.system.scheduler.schedule(
0.microseconds, 30.minutes, self, "clean")
}
def receive = {
case "update" => updateDB()
case "clean" => clean()
}
def updateDB(): Unit ={
Logger.debug("updates running")
}
def clean(): Unit ={
Logger.debug("cleanup running")
}
Hi all,
Before Play 2.4, we had onStart in GlobalSetttings which allowed us to execute some code AFTER the application started.
Since Play 2.4 and the dependency injection orientation, it's recommended to for a class to perform its initialization in it's constructor. The eager binding works well when we want execute some code on start up without injecting the object anywhere, but it's happening before Application is really started.
Is there a way to do the same thing, but after the application started ? Some of the initialization I have in my case need the application to be started. And I don't want to inject those objects in a controller, just to get the constructor called after the application started....
Thanks for your help
class Scheduler @Inject() (
system: ActorSystem,
@Named("voucher-generator") voucherGenerator: ActorRef,
@Named("voucher-cleaner") voucherCleaner: ActorRef) {
// Schedule jobs
QuartzSchedulerExtension(system).schedule("VoucherGenerator", voucherGenerator, VoucherGenerator.Generate)
QuartzSchedulerExtension(system).schedule("VoucherCleaner", voucherCleaner, VoucherCleaner.Clean)
// Start immediately on initialization
voucherGenerator ! VoucherGenerator.Generate
voucherCleaner ! VoucherCleaner.Clean
}
class JobModule extends ScalaModule with AkkaGuiceSupport {
def configure() = {
bindActor[VoucherCleaner]("voucher-cleaner")
bindActor[VoucherGenerator]("voucher-generator")
bind[Scheduler].asEagerSingleton()
}
}
class JobModule extends AbstractModule with AkkaGuiceSupport {
def configure() = {
bindActor[SchedulerActor]("scheduler-actor")
bind(classOf[Scheduler]).asEagerSingleton()
}
}
class Scheduler @Inject() (system: ActorSystem, @Named("scheduler-actor") schedulerActor: ActorRef)(implicit ec: ExecutionContext)
{
val dbupdate = system.scheduler.schedule(
0.microseconds, 5.second, schedulerActor, "update")
val pictureClean = Akka.system.scheduler.schedule(
0.microseconds, 1.minutes, schedulerActor, "clean")
}
class SchedulerActor @Inject() (updater: Updater) extends Actor {
def receive = {
case "update" => updateDB()
case "clean" => clean()
}
def updateDB(): Unit ={
Logger.error("updates running")
}
def clean(): Unit ={
Logger.error("cleanup running")
}
}
bind[Scheduler].asEagerSingleton()
You can use a custom app loader.
--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/c2c6d15a-3fd7-43a1-bf36-2ed4a8f3e023%40googlegroups.com.
15:59:56.749 [application-akka.actor.default-dispatcher-19] INFO p.a.l.concurrent.ActorSystemProvider - Starting application default Akka system: application
Starting Scheduling
15:59:56.784 [application-akka.actor.default-dispatcher-19] INFO application - Running 'beforeStart'.
If I try to access anything (like scheduling using the scheduler) it fails w/ saying there is no started application.
play {
modules {
enabled+= "fr.JobModule"
}
package fr
import akka.actor._
import com.google.inject.AbstractModule
import fr.v1.services.AlerteService
import play.api.Logger
import play.api.libs.concurrent.AkkaGuiceSupport
import scala.concurrent.duration._
class JobModule extends AbstractModule with AkkaGuiceSupport {
def configure() = {
bindActor[SchedulerActor]("scheduler-actor")
}
}
class SchedulerActor extends Actor {
import context.dispatcher
context.system.scheduler.schedule(10.second, 1.minute, self, "update")
val service: AlerteService = AlerteService
def receive = {
case "update" => updateDB()
}
def updateDB(): Unit = {
Logger.error("updates running")
service.purgeAlerte()
}
}
Thanks kévin
--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/1ab652d0-73bd-42a5-95c7-b36444d62d4d%40googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/d060ffc1-0784-4d4d-9476-cc0bfd20f6c0%40googlegroups.com.
I'm using compile time dependency injection and I would like to execute some code after application startup.
That code has to be executed not earlier that after application has started, because it depends on `Play.current`.
Hi Christian,
Right now, we moved away 99% of the code we had in GlobalSetting (onStop, onError, onRequest etc...).
But because I can't find a way to add a start hook on the application life cycle, we still have to use Global but just the onstart(Application app) method.
We use app.injector() .instanceOf method to initialize a couple of stuff and that's all.
Cheers,
Tuesday 30 June 2015 22:15:55 UTC+10, Christian Kaps wrote :Hi,I would also be interested in this topic. We follow the same approach to initialize some Akka jobs on application start.Best regards,Christian
Am Dienstag, 30. Juni 2015 09:48:55 UTC+2 schrieb Eddie:Hi James,
Thanks for your help, but I'm still not sure how to proceed.
Let me try to be more clear with an example: I have a service initializing some background tasks with Akka.system(). This initialization only needs to be done once, but I can't use an eager singleton because the instance would be created when the application starts up, and at this point Akka.system() is not available yet.
What I'm looking for is a way to add a start hook on the ApplicationLifecyle, just like we have a addStopHook method on the ApplicationLifecycle class.
Thanks for your help,
On 30 June 2015 11:05:19 UTC+10, James Roper wrote:
On 29 June 2015 at 11:09, Eddie <edouard...@gmail.com> wrote:Hi all,
Before Play 2.4, we had onStart in GlobalSetttings which allowed us to execute some code AFTER the application started.
Since Play 2.4 and the dependency injection orientation, it's recommended to for a class to perform its initialization in it's constructor. The eager binding works well when we want execute some code on start up without injecting the object anywhere, but it's happening before Application is really started.
Is there a way to do the same thing, but after the application started ? Some of the initialization I have in my case need the application to be started.
A Play application doesn't do anything. It consists of many components that do things. So it doesn't make sense to say "I depend on an application being started", since it doesn't make sense to depend on something that does nothing. What is likely is that you depend on some components that the application starts. If that's the case, then simply make those components dependencies of your component.Also, if you really want to depend on the whole application, then @Inject it into your component. Then you will get a fully initialised application.
And I don't want to inject those objects in a controller, just to get the constructor called after the application started....
Thanks for your help
--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/55fb2ed3-bd05-48ad-b5ef-0653dd139e15%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
To unsubscribe from this group and stop receiving emails from it, send an email to play-framework+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/a5a5e83a-9da8-4068-b8a3-f4461bd32e53%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.