Play Scala Akka内で、DIをしたい
解決済
回答 1
投稿
- 評価
- クリップ 1
- VIEW 2,141
Play Framework 2.5.x(Scala)にて、Akkaを利用して、定期的に、ジョブを実行しようとしてます。
定期的に実行されるプログラムに、DIを利用して、Databaseを処理するクラスの設定を行っているのですが、
DIの設定方法が悪いせいか、下記のエラーが発生します。
[info] Compiling 1 Scala source to /Users/you/Documents/Aiko/Source/aiko-batch-play/target/scala-2.11/classes...
[error] application -
! @74efp4d43 - 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.IllegalArgumentException: no matching constructor found on class models.ClearDBActor for arguments []
at services.CronJob.<init>(CronJob.scala:22)
at services.CronJob.class(CronJob.scala:22)
while locating services.CronJob
at Module.configure(Module.scala:11) (via modules: com.google.inject.util.Modules$OverrideModule -> Module)
while locating services.Cron
1 error]
at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:180)
at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:131)
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:131)
at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1.apply(DevServerStart.scala:129)
at scala.util.Success.flatMap(Try.scala:231)
at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:129)
at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:121)
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.CreationException: Unable to create injector, see the following errors:
1) Error injecting constructor, java.lang.IllegalArgumentException: no matching constructor found on class models.ClearDBActor for arguments []
at services.CronJob.<init>(CronJob.scala:22)
at services.CronJob.class(CronJob.scala:22)
while locating services.CronJob
at Module.configure(Module.scala:11) (via modules: com.google.inject.util.Modules$OverrideModule -> Module)
while locating services.Cron
1 error
at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:466)
at com.google.inject.internal.InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:184)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:110)
at com.google.inject.Guice.createInjector(Guice.java:96)
at com.google.inject.Guice.createInjector(Guice.java:84)
at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:181)
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:168)
at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1$$anonfun$2.apply(DevServerStart.scala:164)
Caused by: java.lang.IllegalArgumentException: no matching constructor found on class models.ClearDBActor for arguments []
at akka.util.Reflect$.error$1(Reflect.scala:81)
at akka.util.Reflect$.findConstructor(Reflect.scala:105)
at akka.actor.NoArgsReflectConstructor.<init>(IndirectActorProducer.scala:103)
at akka.actor.IndirectActorProducer$.apply(IndirectActorProducer.scala:60)
at akka.actor.Props.producer(Props.scala:131)
at akka.actor.Props.<init>(Props.scala:144)
at akka.actor.Props$.apply(Props.scala:86)
at services.CronJob.<init>(CronJob.scala:26)
at services.CronJob$$FastClassByGuice$$50d5309f.newInstance(<generated>)
at com.google.inject.internal.cglib.reflect.$FastConstructor.newInstance(FastConstructor.java:40)
Injectionに登録する際に、指定のクラスのコンストラクタがみつからないですよということですが、どのように登録してあげればよいか方法がわからずにおります。
▼Module.scala
import com.google.inject._
import models.ClearDBActor
import play.api.libs.concurrent.AkkaGuiceSupport
import services._
class Module extends AbstractModule with AkkaGuiceSupport {
override def configure() = {
bind(classOf[Cron]).to(classOf[CronJob]).asEagerSingleton()
}
}
▼CronJob.scala
package services
import com.google.inject._
import play.api.libs.concurrent.Akka
import akka.actor.{Actor, ActorRef, ActorSystem, Props}
import com.google.inject.ImplementedBy
import scala.concurrent.ExecutionContext.Implicits.global
import play.api.inject.ApplicationLifecycle
import scala.concurrent.{ExecutionContext, Future}
import com.typesafe.akka.extension.quartz.QuartzSchedulerExtension
import models.ClearDBActor
import models.dao.RustPrevDao
import play.api.db.slick.DatabaseConfigProvider
import play.api.i18n.MessagesApi
@ImplementedBy(classOf[CronJob])
trait Cron
@Singleton
class CronJob @Inject()(protected val dbConfigProvider: DatabaseConfigProvider, val messagesApi: MessagesApi, rustPrevDao: RustPrevDao, system: ActorSystem, lifeCycle: ApplicationLifecycle)(implicit executionContext: ExecutionContext) extends Cron {
import scala.concurrent.duration._
val ClearDBActor = system.actorOf(Props(classOf[ClearDBActor]))
QuartzSchedulerExtension(system).schedule("ClearDB", ClearDBActor, "")
}
こちらのサイトを参考にさせて頂きました。
http://zuqqhi2.com/scala-play-request-driven
大変、お手数をおかけしますが、ご教授宜しくお願い致します。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
check解決した方法
0
自己解決しました。
下記のURLに書いてあったのですが、コンストラクタ付きのものを呼び出す方法が記載してありました。
▼CronJob
@Singleton
class CronJob @Inject()(protected val dbConfigProvider: DatabaseConfigProvider, val messagesApi: MessagesApi, rustPrevDao: RustPrevDao, system: ActorSystem, lifeCycle: ApplicationLifecycle)(implicit executionContext: ExecutionContext) extends Cron {
import scala.concurrent.duration._
val actor = system.actorOf(ClearDBActor.props(rustPrevDao))
QuartzSchedulerExtension(system).schedule("ClearDB", actor, "")
}
▼ClearDBActor
object ClearDBActor {
def props(rustPrevDao: RustPrevDao) = Props(new ClearDBActor(rustPrevDao))
}
//class ConfiguredActor @Inject() (configuration: Configuration) extends Actor {
// import ConfiguredActor._
//
// val config = configuration.getString("my.config").getOrElse("none")
class ClearDBActor @Inject()(rustPrevDao: RustPrevDao) extends Actor {
def receive = {
case msg: String => {
val shots = rustPrevDao.limitSearch()
Logger.info("Old DB records were cleared.")
}
}
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.11%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる