2016-01-13 2 views
0

Я написал (с Eclipse) небольшую программу, которая использует JPA. Теперь я хочу вручную скомпилировать и запустить эту программу с помощью командной строки. Я также разместил все исходные файлы в отдельном каталоге (не в рабочем пространстве Eclipse). Каталог выглядит следующим образом:PersistenceException: поставщик с постоянством для EntityManager с именем

directory 
    |- src 
    | |- javax 
    | | |- persistence 
    | |  |- <...> 
    | |- main 
    | |- META-INF 
    | | |- javax 
    | | | |- persistence 
    | | |- persistence.xml 
    | | 
    | |- <..> 
    |- run.bat 

Примечание: Я нарочно есть 2 javax каталоги со всеми файлами классов в них.

run.bat содержит строки:

javac -cp ./src ./src/main/Main.java 
java -cp ./src main.Main 

Насколько я понимаю, я получаю ошибки не из-за проблемы с META-INF файл/persistence.xml (не так, как много других людей на StackOverflow) , Я говорю так, потому что я прописан следующие строки в моем Main:

<...> 
Thread.currentThread().setContextClassLoader(new ClassLoader() { 
      @Override 
      public Enumeration<URL> getResources(String name) throws IOException { 
       System.out.println("resource requested=" + name); 
       if (name.equals("META-INF/services/javax.persistence.spi.PersistenceProvider")) { 
     <--- MARK --->  return Collections.enumeration(Arrays.asList(new File("src/javax/persistence/spi/PersistenceProvider.class") 
          .toURI().toURL())); 
       } else if (name.equals("META-INF/persistence.xml")) { 
        return Collections.enumeration(Arrays.asList(new File("src/META-INF/persistence.xml") 
          .toURI().toURL())); 
       } 
       return super.getResources(name); 
      } 
     }); 
emFactory = Persistence.createEntityManagerFactory("uzduotis"); 
<...> 

Итак, когда я запускаю run.bat программа печатает:

resource name=name=META-INF/services/javax.persistence.spi.PersistenceProvider

(он никогда не попадает в ту часть, где программа просит "META-INF/persistence.xml" ресурс)

то ломается и дает мне ошибку:

enter image description here

Если я изменяю ОТМЕТИЛИ заявление

return super.getResources("src/" + name); 

то ошибка говорит только:

enter image description here

Что мне не хватает?

Peristence.xml:

enter image description here

EDIT: Программа Prety проста: нет спящего режима, всего несколько классов, которые извлекать некоторую информацию от REST службы и работы с ним, в основном с использованием javax и внешние библиотеки w3c. Фото исследователя проекта, чтобы показать его простоту.

enter image description here

EDIT 2. РЕШЕНИЕ

Я нашел способ, чтобы заставить его работать, хотя я не совсем уверен, о причинах. Так если кто-нибудь может ответить, почему следующие изменения решить вопрос, который я бы с удовольствием отметить его в качестве ответа

я добавил EclipseLink и MySQL-разъем-Java баночки с Src каталог. eclipselink.jar исправил проблему, и mysql-connector-java.jar был необходим, потому что я получил другую ошибку (я работаю с базой данных afterall). Наконец, я изменил строку в перспективе.летучая мышь файл из

java -cp ./src main.Main 

в

java -cp ./src;./src/eclipselink.jar;./src/mysql-connector-java.jar; main.Main 
+0

Возможно, этот ответ может помочь: http://stackoverflow.com/a/1285436/1506009 – Rozart

+0

Какая часть этого сообщения действительно может решить мою проблему? – sdafsDGZvb

+0

Ну, похоже, что вы не указали поставщика персистентности в файле persistence.xml. Поэтому я попытаюсь указать его как в связанном ответе. Просто попробуйте добавить ' org.hibernate.ejb.HibernatePersistence' inside '<константа unit name =" uzduotis ">' element. Помните, что вам нужно иметь зависимости, разрешенные для HibernatePersistence. – Rozart

ответ

0

кажется, что ваше приложение является стандартным приложением Java SE. JPA не работает автоматически, поскольку стандартная среда Java SE не содержит никакой реализации интерфейсов JPA. Кажется, что Eclipse добавляет eclipselink в classpath под обложку, поэтому ваша программа работает, когда вы запускаете ее из Eclipse. Но когда вы запускаете свою программу из командной строки, вам нужно добавить eclipselink, которая представляет собой библиотеку, которая содержит функциональные возможности для интерфейсов JPA.

Вы можете попытаться сгенерировать файл сборки Ant из проекта eclipse, и вы увидите, добавляет ли он eclipselink в путь к классам в файле build.xml. Или даже лучше, я рекомендую превратить ваш проект в проект с помощью Maven build - вы могли бы создать и запустить свой проект с помощью команды Maven так же, как Eclipse выполнил бы его (поскольку Eclipse использует Maven под обложкой для Maven-based проекты).

Edit - объяснение роли EclipseLink в JPA

пакетов начиная javax.persistence в основном интерфейсы, аннотации, они имеют очень мало классов в самом деле. Они определяют только то, как ваше приложение взаимодействует с основным механизмом сохранения в стандартном режиме. С другой стороны, вам нужно включить также библиотеку с реализациями (классами) для стандартных интерфейсов JPA. javax.persistence.Persistence - это просто фасад, который делегирует всю тяжелую работу на реализацию, которая может быть Eclipselink, Hibernate или что-то еще.

Связь между javax.persistence и EclipseLink аналогична взаимосвязи между интерфейсами и классами. Вы можете использовать интерфейсы в своем коде, но ваше приложение будет работать, только если вы предоставите интерфейсы с реальными классами в какой-то момент.

Также можно использовать Eclipselink напрямую и пропустить весь слой javax.persistence, так же как можно работать с реальными классами напрямую без интерфейсов. Но тогда вам нужно изучить внутренний API Eclipselink, и невозможно заменить библиотеку Eclipselink для таких альтернатив, как Hibernate. Кроме того, вы не сможете повторно использовать знания API-интерфейса Eclipselink для проекта, который использует Hibernate. Повторное использование стандартного API является наиболее важным для стандартизированных интерфейсов javax.persistence.

Возможно, вам интересно, как API-интерфейс persistence знает, где он должен делегировать требуемую функциональность. Есть несколько крючков, как это можно узнать. Можно включить путь к основному классу реализации в persistence.xml с использованием элемента provider. Или это просто работает, если вы включили Eclipselink в путь к классам, поскольку библиотека Eclipselink содержит специальный текстовый файл по стандартизованному пути, который содержит необходимую информацию. Этот специальный файл находится внутри Eclipselink JAR по пути META-INF/services/javax.persistence.spi.PersistenceProvider - звонит ли звонок?

+0

Можете ли вы рассказать больше о том, что именно делает затмение в этом сценарии и почему у javax нет столь необходимых имплементаций? – sdafsDGZvb

+0

Я добавил больше объяснений в ответ. – OndrejM

+0

Посмотрите на этот вопрос http://stackoverflow.com/questions/19322827/no-persistence-provider-for-entitymanager-named-x/22224589#22224589. Он содержит дополнительные технические данные. – OndrejM

Смежные вопросы