Проверка настойчивости с помощью Arquillian и Tomee8. Тесты проходят, но выдается исключение

Я пытаюсь протестировать свой класс DAO, используя Tomee8 и Arquillian. Я использую Hibernate в качестве поставщика постоянства. Тесты проходят, но исключение завершает сборку.

Исключение:

java.lang.IllegalStateException: Незаконный доступ: этот экземпляр веб-приложения уже остановлен. Не удалось загрузить [org.hibernate.resource.beans.internal.BeansMessageLog. Причина: java.lang.NoClassDefFoundError: org/hibernate/resource/beans/internal/BeansMessageLogger.

На самом деле я не знаю, правильно ли настроены maven и тест. Если кто-то может сказать мне, правильно ли я все устанавливаю и что мне не хватает?

РЕДАКТИРОВАТЬ 1 Я удалил поставщика сохраняемости, в данном случае Hibernate, и использовал сборку от Tomee — OpenJPA. Теперь нет исключений, и maven удается собрать приложение. Похоже, есть какая-то проблема с Hibernate. Я знаю, что Hibernate не включен в Tomee, но я не знаю, как включить его во время развертывания arquillian в библиотеках Tomee.

теперь test-persistence.xml выглядит так:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
                http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
             version="2.2">
    <persistence-unit name="testPU" transaction-type="JTA">
        <jta-data-source>tomeeDS</jta-data-source>
        <properties>
            <property name="javax.persistence.schema-generation.databa  se.action" value="drop-and-create" />
            <property name="javax.persistence.schema-generation.create-database-schemas" value="true" />
            <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
            <property name="openjpa.ConnectionFactoryProperties" value="PrintParameters=true, PrettyPrint=true, PrettyPrintLineLength=72" />
            <property name="openjpa.Log" value="DefaultLevel=INFO, Runtime=INFO, Tool=INFO, SQL=TRACE"/>
        </properties>
    </persistence-unit>
</persistence>

pom.xml

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>

        <maven.compiler.plugin.version>3.8.1</maven.compiler.plugin.version>
        <maven.clean.plugin.version>3.1.0</maven.clean.plugin.version>
        <maven.war.plugin.version>3.2.3</maven.war.plugin.version>

        <tomee.version>8.0.0-M3</tomee.version>
        <tomee.classifier>webprofile</tomee.classifier>

        <javaee.api.version>8.0</javaee.api.version>
        <mysql.connector.version>8.0.15</mysql.connector.version>
        <hibernate.version>5.4.1.Final</hibernate.version>
        <lombok.version>1.18.6</lombok.version>

        <arquillian.version>1.2.0.2</arquillian.version>
        <version.shrinkwrap.resolvers>3.1.3</version.shrinkwrap.resolvers>
        <version.arquillian.persistence>1.0.0.Alpha7</version.arquillian.persistence>
        <junit.version>4.12</junit.version>
        <assertj.core.version>3.11.1</assertj.core.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.arquillian</groupId>
                <artifactId>arquillian-universe</artifactId>
                <version>${arquillian.version}</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
            <dependency>
                <groupId>org.jboss.shrinkwrap.resolver</groupId>
                <artifactId>shrinkwrap-resolver-bom</artifactId>
                <version>${version.shrinkwrap.resolvers}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>${javaee.api.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.connector.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.tomee</groupId>
            <artifactId>arquillian-tomee-remote</artifactId>
            <version>${tomee.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.arquillian.universe</groupId>
            <artifactId>arquillian-junit</artifactId>
            <scope>test</scope>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.arquillian.universe</groupId>
            <artifactId>arquillian-persistence</artifactId>
            <scope>test</scope>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.arquillian.universe</groupId>
            <artifactId>arquillian-transaction-jta</artifactId>
            <scope>test</scope>
            <type>pom</type>
            <exclusions>
                <exclusion>
                    <groupId>org.jboss.arquillian.extension</groupId>
                    <artifactId>arquillian-transaction-jta</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.jboss.shrinkwrap.resolver</groupId>
            <artifactId>shrinkwrap-resolver-depchain</artifactId>
            <scope>test</scope>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-core</artifactId>
            <version>${assertj.core.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.196</version>
            <scope>runtime</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-clean-plugin</artifactId>
                <version>${maven.clean.plugin.version}</version>
                <executions>
                    <execution>
                        <id>auto-clean</id>
                        <phase>initialize</phase>
                        <goals>
                            <goal>clean</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.plugin.version}</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>${maven.war.plugin.version}</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.tomee.maven</groupId>
                <artifactId>tomee-maven-plugin</artifactId>
                <version>${tomee.version}</version>
                <configuration>
                    <tomeeHttpPort>8007</tomeeHttpPort>
                    <tomeeClassifier>${tomee.classifier}</tomeeClassifier>
                    <tomeeVersion>${tomee.version}</tomeeVersion>
                    <context>ROOT</context>
                    <libs>
                        <lib>mysql:mysql-connector-java:${mysql.connector.version}</lib>
                        <lib>org.hibernate:hibernate-core:${hibernate.version}</lib>
                    </libs>
                </configuration>
            </plugin>
        </plugins>
    </build>

arqillian.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<arquillian>
    <container qualifier="tomee" default="true">
        <configuration>
            <property name="httpPort">-1</property>
            <property name="stopPort">-1</property>
            <property name="ajpPort">-1</property>
            <property name="dir">target/tomee-remote</property>
            <property name="appWorkingDir">target/arquillian-remote-working-dir</property>
            <property name="portRange">33001-36000</property>
        </configuration>
    </container>
    <extension qualifier="persistence">
        <property name="defaultDataSource">openejb:Resource/tomeeDS</property>
        <property name="defaultDataSeedStrategy">CLEAN_INSERT</property>
    </extension>
    <extension qualifier="persistence-dbunit">
        <property name="datatypeFactory">org.dbunit.ext.h2.H2DataTypeFactory</property>
    </extension>
</arquillian>

test-persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
                http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
             version="2.2">

    <persistence-unit name="testPU" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>tomeeDS</jta-data-source>

        <properties>
            <property name="tomee.jpa.factory.lazy" value="true"/>
            <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
            <property name="hibernate.hbm2ddl.auto" value="create"/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.generate_statistics" value="true" />
        </properties>
    </persistence-unit>
</persistence>

test-resources.xml

<?xml version="1.0" encoding="UTF-8"?>
<tomee>
        <Resource id="tomeeDS" type="javax.sql.DataSource">
            JdbcDriver = org.h2.Driver
            JdbcUrl = jdbc:h2:file:C:/my_h2_db
            UserName = sa
            Password = sa
            jtaManaged = true
            LogSql = true
        </Resource>
</tomee>

EmployeeRepositoryTest.java

@RunWith(Arquillian.class)
public class EmployeeRepositoryTest {

    @Deployment
    public static Archive<?> createTestArchive() {
        MavenResolverSystem resolver = Maven.resolver();
        WebArchive war = ShrinkWrap.create(WebArchive.class, "test.war");
        war.addPackages(true, "org.atanasov");
        //LIBS
        File[] files = resolver.loadPomFromFile("pom.xml")
                .importCompileAndRuntimeDependencies()
                .resolve()
                .withTransitivity().asFile();
        war.addAsLibraries(files);
        //WEB-INF
        war.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
        war.addAsWebInfResource("test-resources.xml", "resources.xml");
        //resources
        war.addAsResource("test-persistence.xml", "META-INF/persistence.xml");
        System.out.println(war.toString(true));
        return war;
    }

    @EJB
    private EmployeeRepository repository;

    @Test
    public void shouldBeInitialized() {
        assertNotNull(repository);
        assertEquals(0, repository.count());
    }

    @Test
    @UsingDataSet("datasets/employees.xml")
    public void shouldInsertRecords() {
        System.out.println();
        assertEquals(3, repository.count());
        System.out.println(repository.find(1L));
    }
}

test.war

/WEB-INF/
/WEB-INF/classes/
/WEB-INF/classes/org/
/WEB-INF/classes/org/atanasov/
/WEB-INF/classes/org/atanasov/repository/
/WEB-INF/classes/org/atanasov/repository/impl/
/WEB-INF/classes/org/atanasov/repository/impl/EmployeeRepositoryTest.class
/WEB-INF/classes/org/atanasov/repository/impl/BaseCrudRepository.class
/WEB-INF/classes/org/atanasov/repository/impl/EmployeeRepositoryImpl.class
/WEB-INF/classes/org/atanasov/repository/api/
/WEB-INF/classes/org/atanasov/repository/api/CrudRepository$1.class
/WEB-INF/classes/org/atanasov/repository/api/CrudRepository$MatchMode$1.class
/WEB-INF/classes/org/atanasov/repository/api/CrudRepository$MatchMode$2.class
/WEB-INF/classes/org/atanasov/repository/api/CrudRepository$MatchMode$3.class
/WEB-INF/classes/org/atanasov/repository/api/CrudRepository$MatchMode$4.class
/WEB-INF/classes/org/atanasov/repository/api/CrudRepository$MatchMode.class
/WEB-INF/classes/org/atanasov/repository/api/CrudRepository$Order.class
/WEB-INF/classes/org/atanasov/repository/api/CrudRepository.class
/WEB-INF/classes/org/atanasov/repository/api/EmployeeRepository.class
/WEB-INF/classes/org/atanasov/domain/
/WEB-INF/classes/org/atanasov/domain/entities/
/WEB-INF/classes/org/atanasov/domain/entities/BaseEntity.class
/WEB-INF/classes/org/atanasov/domain/entities/Employee.class
/WEB-INF/classes/org/atanasov/service/
/WEB-INF/classes/org/atanasov/service/api/
/WEB-INF/classes/org/atanasov/service/api/EmployeeService.class
/WEB-INF/classes/org/atanasov/service/impl/
/WEB-INF/classes/org/atanasov/service/impl/EmployeeServiceImpl.class
/WEB-INF/classes/org/atanasov/web/
/WEB-INF/classes/org/atanasov/web/rest/
/WEB-INF/classes/org/atanasov/web/rest/ApplicationConfig.class
/WEB-INF/classes/org/atanasov/web/rest/EmployeeEndpoint$1.class
/WEB-INF/classes/org/atanasov/web/rest/EmployeeEndpoint.class
/WEB-INF/classes/META-INF/
/WEB-INF/classes/META-INF/persistence.xml
/WEB-INF/lib/
/WEB-INF/lib/mysql-connector-java-8.0.15.jar
/WEB-INF/lib/protobuf-java-3.6.1.jar
/WEB-INF/lib/hibernate-core-5.4.1.Final.jar
/WEB-INF/lib/jboss-logging-3.3.2.Final.jar
/WEB-INF/lib/javax.persistence-api-2.2.jar
/WEB-INF/lib/javassist-3.24.0-GA.jar
/WEB-INF/lib/byte-buddy-1.9.5.jar
/WEB-INF/lib/antlr-2.7.7.jar
/WEB-INF/lib/jboss-transaction-api_1.2_spec-1.1.1.Final.jar
/WEB-INF/lib/jandex-2.0.5.Final.jar
/WEB-INF/lib/classmate-1.3.4.jar
/WEB-INF/lib/javax.activation-api-1.2.0.jar
/WEB-INF/lib/dom4j-2.1.1.jar
/WEB-INF/lib/hibernate-commons-annotations-5.1.0.Final.jar
/WEB-INF/lib/jaxb-api-2.3.1.jar
/WEB-INF/lib/jaxb-runtime-2.3.1.jar
/WEB-INF/lib/txw2-2.3.1.jar
/WEB-INF/lib/istack-commons-runtime-3.0.7.jar
/WEB-INF/lib/stax-ex-1.8.jar
/WEB-INF/lib/FastInfoset-1.2.15.jar
/WEB-INF/lib/h2-1.4.196.jar
/WEB-INF/beans.xml
/WEB-INF/resources.xml

Я удалил трассировку стека, потому что она была очень длинной. Я надеюсь, что этой информации достаточно.

org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading Illegal access: this web application instance has been stopped already. Could not load org.hibernate.resource.beans.internal.BeansMessageLogger]. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access. java.lang.IllegalStateException: Illegal access: this web application instance has been stopped already. Could not load[org.hibernate.resource.beans.internal.BeansMessageLogger].
Caused by: java.lang.NoClassDefFoundError: org/hibernate/resource/beans/internal/BeansMessageLogger
Caused by: java.lang.ClassNotFoundException: Illegal access: this web application instance has been stopped already. Could not load [org.hibernate.resource.beans.internal.BeansMessageLogger].
Caused by: java.lang.IllegalStateException: Illegal access: this web application instance has been stopped already. Could not load [org.hibernate.resource.beans.internal.BeansMessageLogger].
Aug 27, 2019 4:30:12 PM org.apache.openejb.arquillian.common.TomEEContainer undeploy
INFO: cleaning C:\Temp\javaee8-tomee-webapp-archetype\template\target\arquillian-remote-working-dir\0\test.war
Aug 27, 2019 4:30:12 PM org.apache.openejb.arquillian.common.TomEEContainer undeploy
INFO: cleaning C:\Temp\javaee8-tomee-webapp-archetype\template\target\arquillian-remote-working-dir\0\test
Tests run: 3, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 27.57 sec <<< FAILURE!
org.atanasov.repository.impl.EmployeeRepositoryTest  Time elapsed: 1.484 sec  <<< ERROR!
org.jboss.arquillian.container.spi.client.container.DeploymentException: Unable to undeploy test.war
27-Aug-2019 16:30:12.794 SEVERE [http-nio-33004-exec-9] org.apache.openejb.assembler.classic.Assembler.destroyApplication undeployException original cause java.lang.Exception: persistence-unit: testPU -2068767132localhost: org/hibernate/resource/beans/internal/BeansMessageLogger

person Vasil Atanasov    schedule 27.08.2019    source источник
comment
Не могли бы вы повторить попытку с последним выпуском TomEE 8.0.0 и обновленной версией Hibernate 5.4.9.Final (вместо 5.4.1.Final)? Пожалуйста, сообщите, если это вылечит вашу установку?   -  person MWiesner    schedule 15.11.2019


Ответы (1)


Я нашел обходной путь.

Я настроил Maven для сборки библиотек Hibernate с зависимостями и скопировал их в каталог «target/additional-libs». Затем я устанавливаю «additionalLibs» в arquillian.xml и указываю путь к каталогу с библиотеками гибернации.

Здесь решение шаг за шагом:

  1. Отметьте зависимости Hibernate и драйвера источника данных как «предоставленные». В моем случае:
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>5.4.8.Final</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>com.vladmihalcea</groupId>
    <artifactId>hibernate-types-52</artifactId>
    <version>2.7.1</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>42.2.8</version>
    <scope>provided</scope>
</dependency>
  1. Создайте файл сборки src/test/resources/assembly.xml со следующим содержимым:
<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">

    <id>libs</id>

    <formats>
        <format>dir</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>

    <dependencySets>
        <dependencySet>
            <includes>
                <include>org.postgresql:postgresql:jar:</include>
                <include>org.hibernate:hibernate-entitymanager</include>
                <include>com.vladmihalcea:hibernate-types-52</include>
            </includes>
            <useTransitiveDependencies>true</useTransitiveDependencies>
            <useTransitiveFiltering>true</useTransitiveFiltering>
            <scope>provided</scope>
        </dependencySet>
    </dependencySets>

</assembly>
  1. В пом.xml:
<build>
    <plugins>
        ...
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>3.2.0</version>
            <configuration>
                <descriptors>
                    <descriptor>src/test/resources/assembly.xml</descriptor>
                </descriptors>
                <attach>false</attach>
                <!-- libraries placed in target/additional-libs. "finalName" specify first part of directory name, second part is constructed in assembly.xml from "id" tag -->
                <finalName>additional</finalName>
                <outputDirectory>target</outputDirectory>
            </configuration>
            <executions>
                <execution>
                    <id>copy-hibernate-and-postgresql-driver</id>
                    <phase>process-test-classes</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        ...
    </plugins>
</build>
  1. Укажите следующие свойства в arquillian.xml:
<property name="dir">target/tomee-remote</property>
...
<property name="additionalLibs">
    target/additional-libs/*.jar
</property>
...
<property name="catalina_opts">-Djavax.persistence.provider=org.hibernate.jpa.HibernatePersistenceProvider</property> <!-- I use TomEE plus -->

В результате библиотеки копируются в папку "lib" извлеченного каталога tomee. Одно странное поведение сборки Maven - имя каталога состоит из двух частей, одна из части pom.xml (шаг 3), а вторая - из тега «lib» на шаге 2. Я не нашел способ указать имя каталога в одном месте.

person Makarov Alexey    schedule 18.11.2019