2016-04-27 7 views
3

РЕДАКТИРОВАТЬ: Несмотря на то, что (хороший) ответ был задан и присужден, это касается лишь незначительной части моего вопроса. Основные части этого вопроса все еще открыты.JPA/EclipseLink: Понимание проблем ClassLoader

Я использую EclipseLink (2.6.2) в облачном проекте. Проект представляет собой веб-приложение, упакованное как файл WAR и развернутое на Apache Tomcat 8. Контекст персистентности настраивается с использованием кода Java, где я указываю объекты, которые будут использоваться с использованием . Эта конфигурация обычно работает так, как ожидалось, где точно определены классы сущностей в указанных пакетах.

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

При запуске на Apache Tomcat, включая пул соединений Tomcat, экземпляр DataSource создается с использованием плагина spring-cloud-connector (spring-cloud-spring-service-connector). В этой настройке все работает так, как ожидалось, до тех пор, пока я не изменяю загрузчик классов, как описано ниже (иначе я сталкиваюсь с ClassNotFoundException s для классов сущностей).

При выполнении модульных тестов с помощью JUnit и spring-test экземпляр DataSource создается с помощью H2 базы данных в оперативной памяти (с использованием EmbeddedDatabaseBuilder из spring-jdbc). В этом параметре я должен указать JPA для использования загрузчика классов, используемого для экземпляра DataSource (ключ eclipselink.classloader в карте свойств JPA), в противном случае я получаю «Object ... не известный тип Entity».

При выполнении тестов во встроенном Apache Tomcat 8 я не вижу сообщений о пуле подключений. В этом параметре я также должен установить загрузчик классов как для модульных тестов.

Если добавить commons-dbcp (2.1.1) для моего проекта и явно настроить spring-cloud-connector плагин использовать его вместо пула соединений Tomcat, я могу запустить приложение на Tomcat без настройки загрузчика классов, но он также работает с загрузчиком классов описанной выше.

Для тестов commons-dbcp ничего не меняет по сравнению с описанными выше сценариями (поскольку соответствующая конфигурация не используется).

Резюме:

  • Tomcat (Tomcat CP): только с помощью немодифицированной загрузчик классов для JPA
  • Tomcat (ГСБД): оба варианта
  • Тесты: только с помощью загрузчика классов DataSource «s для JPA

Не могли бы вы помочь мне разобраться в различиях здесь и предложить простое решение, подходящее для всех случаев? Я предполагаю, что DBCP и Spring используют другой загрузчик классов, чем Tomcat (и пул соединений Tomcat).

Если вам нужна дополнительная информация, я с радостью добавлю ее.

EDIT: Я добавил пример проекта с большим README о том, как воспроизводить.

https://github.com/C-Otto/classloaderexample

+0

Также посмотрите на https://stackoverflow.com/que stions/35318985/spring-cloud-connector-1-2-1-classnotfoundexception-for-entities –

+0

Я не понимаю ваш вопрос. Ваши вопросы смешиваются с DataSource, пулом подключений и службой обнаружения (spring-cloud-service- *). Я думаю, что для вас лучше создать пример с использованием простого проекта в github и задать свои проблемы здесь. – xsalefter

+0

@xsalefter Я добавил пример проекта с некоторой документацией. Спасибо за предложение. –

ответ

5

"Я получаю другую ошибку, когда я начать использовать МВН tomcat7: бег, использовать пула подключений приложения Tomcat (CloudDatabaseConfig) и не перенастроить classloder (JpaConfig):"

You должен настроить зависимость PostreSQL от плагина maven. Вы получаете ClassNot нашли, потому что JAR PostgreSQL не в пути:

<plugin> 
    <groupId>org.apache.tomcat.maven</groupId> 
    <artifactId>tomcat7-maven-plugin</artifactId> 
    <version>2.2</version> 
    <configuration> 
    <port>8080</port> 
    <path>/</path> 
    </configuration> 
    <!-- For any extra dependencies needed when running embedded Tomcat (not WAR dependencies) add them below --> 
    <dependencies> 
    <dependency> 
     <groupId>org.postgresql</groupId> 
     <artifactId>postgresql</artifactId> 
     <version>9.4-1206-jdbc41</version> 
     <scope>runtime</scope> 
    </dependency> 
    </dependencies> 
</plugin> 

также посмотреть на https://tomcat.apache.org/maven-plugin-2.2/run-mojo-features.html

Я забыл включить изменение загрузчика классов на (JpaConfigWithDatasourceClassloader.getJPAProperties):

properties.put(CLASSLOADER, new java.net.URLClassLoader(
    ((java.net.URLClassLoader)classLoader).getURLs(), JpaConfigWithDatasourceClassloader.class.getClassLoader() ) 
) ; 

При этом вы можете запустить все варианты с использованием tomcat7:run

+0

Спасибо, я не знал о зависимостях плагина. Я добавил некоторую информацию к вашему ответу, это действительно помогло. Для проблемы с загрузчиком class: Мне кажется, ваш фрагмент просто показывает другой способ настройки загрузчика классов, который будет использоваться JPA. Я до сих пор не понимаю, почему эта конфигурация необходима вообще и почему она вызывает проблемы в зависимости от пула соединений и настройки запуска/тестирования. –

+0

Я не специалист по загрузке классов Tomcat, но, глядя на код, я представляю, что в Datasource загружен контейнерный загрузчик классов и ваши сущности с загрузчиком классов приложений. Если вы передадите класс класса контейнера в JPA, он не увидит кланов, которые у вас есть в вашей войне. – fhofmann

+0

Объект DataSource построен внутри моего приложения, так что этого не может быть. Но очень вероятно, что реализация пула соединений была создана другим загрузчиком классов и что это вызывает проблемы. –

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