В настоящее время я испытываю немало проблем с созданием тестовой среды блока данных с использованием Arquillian. Мой проект уже работает в среде Glassfish 3.1.2 на основе Seam 3, JSF и MySQL. Однако при попытке настроить тестовую среду с использованием Arquillian все становится неприятно.Arquillian, glassfish & h2database
Моя конечная цель - это модульный тест на основе Аркильяна с использованием встроенного сервера Glassfish и встроенной базы данных h2 в памяти. Я не придирчив, когда дело доходит до встроенного контейнера, просто руководство Arquillian JPA предположило, что минимальный контейнер Weld не поддерживает JPA. Вот почему я отказался от Glassfish. Поскольку я не получаю даже около инициализации контекста персистентности, я не отправляю файл persistence.xml.
Вот POM я закончил с до сих пор:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ch.diction</groupId>
<artifactId>web-portal</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Diction web portal</name>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jee.version>1.0.0.Final</jee.version>
<seam.version>3.1.0.Final</seam.version>
<primefaces.version>3.4</primefaces.version>
<primefaces.theme.version>1.0.8</primefaces.theme.version>
<drools.version>5.4.0.Final</drools.version>
<arquillian.version>1.0.2.Final</arquillian.version>
<arquillian.weld.version>1.0.0.CR3</arquillian.weld.version>
<junit.version>4.8.1</junit.version>
<h2.version>1.3.168</h2.version>
<weldcore.version>1.1.10-SNAPSHOT</weldcore.version>
<slf4j.version>1.6.6</slf4j.version>
</properties>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<testSourceDirectory>src/test/java</testSourceDirectory>
<outputDirectory>target/main</outputDirectory>
<testOutputDirectory>target/test</testOutputDirectory>
<resources>
<resource>
<targetPath>ch/diction/webportal/resources</targetPath>
<directory>src/main/resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<targetPath>ch/diction/webportal/resources</targetPath>
<directory>src/test/resources</directory>
</testResource>
<testResource>
<targetPath>ch/diction/webportal/resources</targetPath>
<directory>src/main/resources</directory>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>jboss-public-repository-group</id>
<name>JBoss Public Maven Repository Group</name>
<url>http://repository.jboss.org/nexus/content/groups/public</url>
</repository>
<repository>
<id>Java.Net</id>
<name>Java Maven Repository</name>
<url>http://download.java.net/maven/2/</url>
</repository>
<repository>
<id>prime-repo</id>
<name>PrimeFaces Maven Repository</name>
<url>http://repository.primefaces.org</url>
<layout>default</layout>
</repository>
</repositories>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.seam</groupId>
<artifactId>seam-bom</artifactId>
<version>${seam.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>${arquillian.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>${primefaces.version}</version>
</dependency>
<dependency>
<groupId>org.primefaces.themes</groupId>
<artifactId>redmond</artifactId>
<version>${primefaces.theme.version}</version>
</dependency>
<dependency>
<groupId>org.jboss.seam.security</groupId>
<artifactId>seam-security</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${drools.version}</version>
<exclusions>
<exclusion>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jboss.seam.persistence</groupId>
<artifactId>seam-persistence</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.solder</groupId>
<artifactId>solder-impl</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.seam.transaction</groupId>
<artifactId>seam-transaction</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.seam.international</groupId>
<artifactId>seam-international-api</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.seam.international</groupId>
<artifactId>seam-international</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.jboss.seam.faces</groupId>
<artifactId>seam-faces</artifactId>
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-glassfish-embedded-3.1</artifactId>
<version>1.0.0.CR3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.main.extras</groupId>
<artifactId>glassfish-embedded-all</artifactId>
<version>3.1.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>juli</artifactId>
<version>6.0.13</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Я думаю, на этот пост, только «зависимости Тест» имеют важное значение (см комментарий маркер), так как фактический главный Deploy работает безупречно. Запуск следующего испытания блока:
package ch.diction.webportal.test.glossary.model;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.UserTransaction;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.seam.security.SecurityInterceptor;
import org.jboss.seam.transaction.TransactionInterceptor;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import ch.diction.webportal.glossary.entity.Glossary;
import ch.diction.webportal.glossary.model.IGlossaryDataAccessObject;
import ch.diction.webportal.glossary.model.JpaGlossaryDataAccessObject;
import ch.diction.webportal.security.seam.producer.EntityManagerProducer;
@RunWith(Arquillian.class)
public class JpaGlossaryDataAccessObjectTest {
@Deployment
public static Archive<?> createDeployment() {
final Archive<?> ar = ShrinkWrap
.create(WebArchive.class, "test.war")
.addPackage(Glossary.class.getPackage())
.addClass(SecurityInterceptor.class)
.addClass(TransactionInterceptor.class)
.addClass(EntityManagerProducer.class)
.addClass(JpaGlossaryDataAccessObject.class)
.addAsWebInfResource("ch/diction/webportal/resources/security/beans.xml", "beans.xml")
.addAsResource("ch/diction/webportal/resources/persistence/persistence.xml", "META-INF/persistence.xml");
return ar;
}
@Inject
private IGlossaryDataAccessObject dao;
@PersistenceContext
private EntityManager entityManager;
@Inject
private UserTransaction userTransaction;
private void clearData() throws Exception {
userTransaction.begin();
entityManager.joinTransaction();
entityManager.createQuery("delete from Glossary").executeUpdate();
userTransaction.commit();
}
@After
public void commitTransaction() throws Exception {
userTransaction.commit();
}
private void insertData() throws Exception {
userTransaction.begin();
entityManager.joinTransaction();
// TODO: Insert records
userTransaction.commit();
entityManager.clear();
}
@Before
public void preparePersistenceTest() throws Exception {
clearData();
insertData();
startTransaction();
}
private void startTransaction() throws Exception {
userTransaction.begin();
entityManager.joinTransaction();
}
@Test
public void testCreateEmptyGlossary() {
final Glossary glossary = new Glossary("empty");
dao.store(glossary);
}
}
Теперь дает мне со следующим исключением:
Caused by: java.lang.VerifyError: class com.sun.enterprise.web.WebModule overrides final method stop.()V
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2404)
at java.lang.Class.getConstructor0(Class.java:2714)
at java.lang.Class.newInstance0(Class.java:343)
at java.lang.Class.newInstance(Class.java:325)
at com.sun.hk2.component.ConstructorCreator.create(ConstructorCreator.java:65)
... 79 more
Что касается этого, я совершенно невежественны. Я даже не знал, что такие исключения существуют в java o.O ...
Заранее благодарим за любые предложения здесь! Любая помощь приветствуется!
С наилучшими пожеланиями Паскаль
Я думаю, что проблема в том, что встроенный контейнер имеет один и тот же путь к классу со всеми вашими зависимостями, поэтому такие проблемы могут возникнуть. Например, с встроенным GlassFish вам нужно быть осторожным с Google Guava :) Аркиллианские парни знают об этих ограничениях и предпринимают постоянные попытки сделать проблемы с загрузкой менее болезненными для встроенных контейнеров. –
Еще одно преимущество наличия удаленного контейнера заключается в том, что вы сэкономите время на его загрузку для каждого тестового класса => более быстрая обратная связь. –