2016-07-09 3 views
1

Я пытаюсь вставить JPAApi в свой контроллер с помощью Play 2.5, но я продолжаю получать следующее исключение.Play Framework Inject Error

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 – greyfox

+0

DOM4J не найден (или одна из его зависимостей) ... как говорится в сообщении. –

ответ

7

Вы только что столкнулись с ошибкой в ​​sbt (используется инструмент построения Play). Эта ошибка возникает с версией 5.2.1 Hibernate (но не с 5.2.0).

Hibernate 5.2.1 начал исключать все транзитивные зависимости dom4j с синтаксисом maven, который sbt пока не может быть обработан.

Обойти теперь добавить

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

к вашему libraryDependencies в build.sbt (параллельно с зависимостью гибернации).

Для получения более подробной информации, посмотрите на самом sbt ошибка, которую можно найти здесь: https://github.com/sbt/sbt/issues/1431

Исправлена ​​ошибка Hibernate я сообщил (но был закрыт, как оказалось, чтобы быть sbt вопрос) можно найти здесь: https://hibernate.atlassian.net/browse/HHH-10916

+0

Да, добавив эту строчку, все исправлено, спасибо! – greyfox

+0

Человек вы рок! Благодарю. – Aphax

+0

sbt 0.13.13 исправил ошибку, поэтому это обходное решение больше не нужно. – mkurz

0

на основе небольшого фрагмента, который вы предоставили. Я убежден в том, что вы используете API-интерфейс Play Java. Принимая во внимание, я сначала рекомендую вам обратиться к Play documentation об инъекции зависимостей.

если вы бутстрапированная свой проект, используя один из шаблонов Активатор, вы, вероятно, в конечном итоге со следующими двумя файлами (среди многих других):

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

«модулей» один из способов настройки привязок в Guice (в основном, что Guice будет возвращать, когда компонент запрашивает инъекцию определенного типа).

в интересах получения вас и работает в то же время ...

... первый в application.conf файле под play.modules раздел, раскомментируйте строку, чтобы добавить в разрешенном набор модулей, так что вы будете в конечном итоге с чем-то вроде этого:

play.modules { 
    enabled += Module 
} 

... рядом, если у вас есть интерфейс с именем JPAApi с конкретной реализацией JPAApiImpl ... обновить Module.java следующим образом:

import com.google.inject.AbstractModule; 

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

(или если JPAApi само по себе является конкретной реализацией, можно просто связать, что само по себе)

перезапустить приложение, и контроллер должен быть введен.

+0

Воспроизведение делает всю конфигурацию Guice. Связывание JPAAPi выполняется в Play, для этого не требуется объявлять модуль. Ошибка не возникает из-за неправильной настройки Guice (она не должна). Я думаю, что проблема связана с конфигурацией db. – asch

+0

@AlaSchneider - ah-ha, спасибо за отзыв! поэтому я думаю, что подключение ваших собственных модулей необходимо только для настройки привязок? – hsl