2016-07-09 12 views
1

Play 2.5を使用してJPAApiを私のコントローラに注入しようとしていますが、次の例外が続きます。Play Framework注入エラー

com.google.inject.ProvisionException:プロビジョニングすることができない、次のエラーを参照してください。

1) Error injecting constructor, java.lang.NoClassDefFoundError: org/dom4j/io/STAXEventReader 
    at play.db.jpa.DefaultJPAApi$JPAApiProvider.<init>(DefaultJPAApi.java:39) 
    at play.db.jpa.DefaultJPAApi$JPAApiProvider.class(DefaultJPAApi.java:34) 
    while locating play.db.jpa.DefaultJPAApi$JPAApiProvider 
    while locating play.db.jpa.JPAApi 
    for parameter 0 at controllers.HomeController.<init>(HomeController.java:20) 
    while locating controllers.HomeController 
    for parameter 1 at router.Routes.<init>(Routes.scala:40) 
    while locating router.Routes 
    while locating play.api.inject.RoutesProvider 
    while locating play.api.routing.Router 
    for parameter 0 at play.api.http.JavaCompatibleHttpRequestHandler.<init>(HttpRequestHandler.scala:200) 
    while locating play.api.http.JavaCompatibleHttpRequestHandler 
    while locating play.api.http.HttpRequestHandler 
    for parameter 4 at play.api.DefaultApplication.<init>(Application.scala:221) 
    at play.api.DefaultApplication.class(Application.scala:221) 
    while locating play.api.DefaultApplication 
    while locating play.api.Application 

1 error 
    com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1025) 
    com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1051) 
    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:123) 
    play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21) 
    play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1$$anonfun$2.apply(DevServerStart.scala:158) 
    play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1$$anonfun$2.apply(DevServerStart.scala:155) 
    play.utils.Threads$.withContextClassLoader(Threads.scala:21) 
    play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:155) 
    play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(DevServerStart.scala:126) 
    scala.Option.map(Option.scala:146) 
    play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1.apply(DevServerStart.scala:126) 
    play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1$$anonfun$apply$1.apply(DevServerStart.scala:124) 
    scala.util.Success.flatMap(Try.scala:231) 
    play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:124) 
    play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:116) 
    scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24) 
    scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24) 
    java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402) 
    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) 

これは私のコントローラです。

public class HomeController extends Controller { 

    private JPAApi jpaApi; 

    @Inject 
    public HomeController(JPAApi jpaApi) { 
     this.jpaApi = jpaApi; 
    } 

    public Result index() { 
     jpaApi.withTransaction(entityManager -> { 
      Query query = entityManager.createNativeQuery("select max(age) from people"); 
      return (Long) query.getSingleResult(); 
     }); 
     return ok(index.render("Your new application is ready.")); 
    } 

} 
+0

1)あなたは 'java.lang 'を持っています。NoClassDefFoundError:org/dom4j/io/STAXEventReader' - この依存関係は設定されていますか? 2)あなたのGuice設定はどのように見えますか? – hsl

+0

私が次の例は、Guiceを構成する必要性について何も言及していません。 Guiceに関連すると思われるModuleクラスがあります – greyfox

+0

DOM4Jが見つからない(またはその依存関係の1つ)...というメッセージが表示されます。 –

答えて

7

ちょうどsbt(Playツールが使用している)のバグにぶつかりました。 このバグは、Hibernateバージョン5.2.1では発生しますが(5.2.0では発生しません)。

Hibernate 5.2.1 started のmavenの構文ですべての推移的な依存関係を除外しました。sbtはまだ処理できません。今の

回避策は(Hibernateの依存関係に平行に)build.sbtであなたのlibraryDependencies

"dom4j" % "dom4j" % "1.6.1" intransitive() 

を追加することです。詳細については

ここで見つけることができますsbtバグそのものを見て:私は報告している(それはsbt問題であることが判明したとして、閉じられていた)、Hibernateのバグを見つけることができるhttps://github.com/sbt/sbt/issues/1431

ここでは: https://hibernate.atlassian.net/browse/HHH-10916

+0

はい、この行を追加するとすべてが修正されました。ありがとう! – greyfox

+0

あなたはロック!ありがとう。 – Aphax

+0

sbt 0.13.13がこのバグを修正しましたので、この回避策はもう必要ありません。 – mkurz

0

私があなたがPlay Java APIを使用していると仮定して実行している小さなスニペットに基づいています。多くの場合、私は最初に、あなたが依存性注入に関するPlay documentationを参照することをお勧めします。

あなたはおそらく、(他の多くの間で)次の2つのファイルになってしまった、アクティベーターテンプレートのいずれかを使用してプロジェクトをブートストラップした場合:

. 
├── app 
│   ├── Module.java 
└── conf 
   └── application.conf 

「モジュールは、」でバインディングを構成する一つの方法ですGuice(基本的にGuiceはコンポーネントが特定の型の注入を要求したときに返すもの)その間にあなたを取得し、実行しているの利益のために

...

は...まず、play.modulesセクションの下application.confファイルで、有効セットに追加する行のコメントを解除しました

を次のように Module.javaを更新...あなたは具体的な実装 JPAApiImplJPAApiという名前のインターフェイスを持っていると仮定すると、次の...

play.modules { 
    enabled += Module 
} 

:あなたはこのようなものになってしまいますモジュールの、よう

import com.google.inject.AbstractModule; 

public class Module extends AbstractModule { 
    @Override 
    public void configure() { 
     bind(JPAApi.class).to(JPAApiImpl.class); 
    } 
} 

(またはJPAApiは、具体的な実装自体であれば、あなただけの自分自身にそれを結合することができる)

は、アプリケーションを再起動

し、あなたのコントローラが注入されなければなりません。

+0

PlayはGuiceのすべての設定を単独で行います。 JPAAPiバインディングはPlayによって行われますが、モジュールを宣言する必要はありません。 Guiceが構成されていないためにエラーが発生しません。私は問題がdbの設定から来ると思う。 – asch

+0

@AlaSchneider - ah-ha、フィードバックありがとう!だから、自分のモジュールを結ぶのは、バインディングをカスタマイズするだけで必要なのでしょうか? – hsl