Встроенный GlassFish игнорирует ресурсы тестирования Maven - PullRequest
5 голосов
/ 19 июля 2011

У меня есть несколько сессионных компонентов, для которых я написал модульные тесты.Я настроил Maven для включения файла persistence.xml в каталог src / main / resources / META-INF, который ссылается на локальную базу данных MySQL для целей разработки.У меня есть другой файл persistence.xml в каталоге src / test / resources / META-INF, который ссылается на встроенную базу данных Derby __default.Тесты развернуты во встроенном контейнере GlassFish 3.1.

Однако, когда я запускаю тесты, я получаю следующую ошибку:

java.lang.RuntimeException: javax.naming.NamingException: Lookup failed for 'jdbc/mylog' 

jdbc / mylog - это база данных MySQL, в которой модуль персистентностив основном каталоге ссылается на.Очевидно, он игнорирует модуль персистентности в каталоге test, но я понятия не имею, почему.

Maven правильно устанавливает classpath, насколько я могу судить, с помощью test-classes перед классами и просмотра вфактический каталог target / test-classes / META-INF показывает, что он скопировал правильную встроенную единицу сохранения Derby.

[DEBUG] Test Classpath :
[DEBUG]   C:\Users\Laurens\Documents\Projects\Mylog\target\test-classes
[DEBUG]   C:\Users\Laurens\Documents\Projects\Mylog\target\classes
[DEBUG]   C:\Users\Laurens\.m2\repository\org\eclipse\persistence\eclipselink\2.2.0\eclipselink-2.2.0.jar
[DEBUG]   C:\Users\Laurens\.m2\repository\org\eclipse\persistence\javax.persistence\2.0.3\javax.persistence-2.0.3.jar
[DEBUG]   C:\Users\Laurens\.m2\repository\org\eclipse\persistence\org.eclipse.persistence.jpa.modelgen.processor\2.2.0\org.eclipse.persistence.jpa.modelgen.processor-2.2.0.jar
[DEBUG]   C:\Users\Laurens\.m2\repository\org\glassfish\extras\glassfish-embedded-all\3.1\glassfish-embedded-all-3.1.jar
[DEBUG]   C:\Users\Laurens\.m2\repository\javax\javaee-web-api\6.0\javaee-web-api-6.0.jar
[DEBUG]   C:\Users\Laurens\.m2\repository\junit\junit\4.8.1\junit-4.8.1.jar

Любая подсказка о том, как GlassFish использует правильную единицу сохранения, очень ценится!Спасибо!

Ответы [ 3 ]

11 голосов
/ 19 июля 2011

При запуске тестов с использованием встроенного Glassfish провайдер JPA не использует путь к классу, отображаемый в командной строке, перед выполнением цели maven-surefire-plugin (которая используется для запуска фазы тестирования).Embedded Glassfish развертывает артефакты, доступные как часть тестовой области, как ScatteredArchive.Этот разбросанный архив обычно создается в каталоге java.io.tmpdir, обычно с именем gfembed<a_random_number>tmp, если во встроенной конфигурации Glassfish не указано расположение корневого каталога установки Glassfish и домена Glassfish.

Когда встроенный домен Glassfishподготовлен с развернутым разрозненным архивом, файлы для развертывания обычно копируются в разнесенный каталог, в котором находятся все классы (включая все зависимости), необходимые для приложения.Этот каталог обычно присутствует в каталоге GF_EMBED_DOMAIN_HOME/applications/<application_name>.Файлы persistence.xml из ваших каталогов src/main/resources/META-INF и src/test/resources/META-INF копируются сюда в каталог <application-name>/META-INF.Само собой разумеется, тот, который копируется последним, или тот, который не перезаписывается, - это тот, который используется провайдером JPA во время тестов.Это всегда файл в src/main/resources/META-INF.

Эту ситуацию можно преодолеть двумя способами:

1.Использование пользовательского файла конфигурации домена Glassfish

Вы можете указать файл конфигурации домена (domain.xml), который будет содержать определение источника данных для jdbc/mylog.Это то, что я делаю в настоящее время, потому что он очень гибкий, и файл конфигурации домена может содержать и другие конфигурации.Конфигурационный файл необходимо указать как часть настройки теста следующим образом:

Map<String, Object> props = new HashMap<String, Object>();
props.put("org.glassfish.ejb.embedded.glassfish.installation.root", "./glassfish-install/glassfish");
container = EJBContainer.createEJBContainer(props);
context = container.getContext();
datasource = (DataSource) context.lookup("jdbc/mylog"); //You can lookup the datasource too, to confirm that your setup is successful.

Вышеупомянутый каталог glassfish-install и его подкаталог glassfish находятся в корневом каталоге проекта Maven (а также проверен на контроль версий);каталог glassfish должен содержать структуру каталогов domain1/config для представления структуры каталогов домена Glassfish с именем domain1.Структуру в проекте можно увидеть на скриншоте ниже.Другие связанные файлы (JAR-адаптеры ресурсов JDBC и т. П.) Можно получить из установочного каталога Glassfish, но, как правило, они также могут быть размещены в правильном месте встроенной средой выполнения Glassfish, если настроены правильно.*Glassfish domain configuration file location

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

<domain log-root="${com.sun.aas.instanceRoot}/logs" application-root="${com.sun.aas.instanceRoot}/applications" version="10.0">
  <system-applications/>
  <applications/>
  <resources>
    <jdbc-resource pool-name="MyPool" jndi-name="jdbc/mylog"/>
    ...
    <jdbc-connection-pool driver-classname="" datasource-classname="org.apache.derby.jdbc.ClientDataSource" res-type="javax.sql.DataSource" description="" name="MyPool" ping="true">
      <property name="User" value="APP"></property>
      <property name="RetrieveMessageText" value="true"></property>
      <property name="CreateDatabase" value="true"></property>
      <property name="ServerName" value="localhost"></property>
      <property name="Ssl" value="off"></property>
      <property name="SecurityMechanism" value="4"></property>
      <property name="TraceFileAppend" value="false"></property>
      <property name="TraceLevel" value="-1"></property>
      <property name="PortNumber" value="1527"></property>
      <property name="LoginTimeout" value="0"></property>
      <property name="Password" value="APP"></property>
      <property name="databaseName" value="MYDB"></property>
    </jdbc-connection-pool>
    ...
  </resources>
  <servers>
    <server name="server" config-ref="server-config"> 
      <resource-ref ref="jdbc/__TimerPool"/>
      <resource-ref ref="jdbc/__default"/>
      <resource-ref ref="jdbc/mylog"/>
    </server>
  </servers>
  ...
...

Файл default domain.xml по умолчанию можно загрузить с сайта java.net и изменить, если вы хотите сохранить изменениякак можно меньше, вместо копирования одного из установки Glassfish.

2.Копирование файлов persistence.xml

Можно добавить цели в файл POM Maven, выполнить резервное копирование и скопировать файл persistence.xml из src/test/resources/META-INF в src/main/resources/META-INF до фазы test,После завершения фазы тестирования оригинал восстанавливается.Я не буду вдаваться в подробности этого, поскольку подобное решение уже обсуждалось в связанном вопросе StackOverflow .Я не использовал этот подход для интеграционных тестов, так как требовал внесения изменений, отличных от тех, которые можно перенести в persistence.xml, таких как создание настраиваемой области.Однако я использую его для юнит-тестов, поскольку JPA-провайдер будет извлекать файл persistence.xml из target/classes вместо target/test-classes, несмотря на то, что последний появляется первым в порядке пути к классам.Если вы используете Hibernate в качестве поставщика JPA, включение ведения журнала TRACE для регистратора org.hibernate.ejb (поскольку класс Ejb3Configuration отвечает за поиск) убедит вас в том, что файл в test-classes не будет выбран.


Примечание:

Большая часть ответа предполагает использование Glassfish 3.1, но может также подойти и для следующих версий.

0 голосов
/ 04 ноября 2014

Этот ответ может показаться глупым, но я искал способ, который позволил бы мне запустить эти тесты из затмения на Run As -> JUnit Test.Вот как я это сделал:

@BeforeClass
public static void setUp() throws IOException {
    Files.copy(new File("target/test-classes/META-INF/persistence.xml"), new File("target/classes/META-INF/persistence.xml"));
    // ...
}

Я просто копирую test / persistence.xml в classes / persistence.xml.Это работает.

0 голосов
/ 19 июля 2011

Под "встроенным контейнером для стеклянной рыбы" вы подразумеваете плагин maven, который запускает для вас Glassfish? Путь к классам для подключаемого модуля Maven отличается и управляется иначе, чем путь к классам тестирования Maven. Возможно, вам придется работать с другим путем к классам.

...