简体   繁体   English

Arquillian在第一个测试类之后无法注入依赖项

[英]Arquillian fails to inject dependencies after the first test class

I have a slightly weird problem. 我有一个奇怪的问题。 I'm currently using Arquillian (1.1.0.Final) together with Embedded GlassFish (3.1.2.2). 我目前正在使用Arquillian(1.1.0.Final)和Embedded GlassFish(3.1.2.2)。 I used following guide to setup my little test project. 我使用以下指南来设置我的小测试项目。 Everything worked fine with the integrated Derby database. 集成的Derby数据库一切正常。 My real application uses PostgreSQL as a database, so I configured my GlassFish resources as follows: 我的实际应用程序使用PostgreSQL作为数据库,因此我对GlassFish资源进行了如下配置:

    <!-- See http://jdbc.postgresql.org/documentation/91/ds-cpds.html -->
    <jdbc-connection-pool name="MyPostgresqlPool"
                          res-type="javax.sql.DataSource"
                          datasource-classname="org.postgresql.ds.PGSimpleDataSource"
                          is-isolation-level-guaranteed="false">

        <property name="user" value="..." />
        <property name="databaseName" value="..." />
        <property name="password" value="..." />
        <property name="serverName" value="..." />
        <property name="portNumber" value="..." />

    </jdbc-connection-pool>

And I access the persistence context and the user transaction as described in above guide: 然后按照上述指南中的说明访问持久性上下文和用户事务:

@RunWith(Arquillian.class)
public class AddressModuleTest extends BaseTest {
    @PersistenceContext
    protected EntityManager em;

    @Inject
    protected UserTransaction utx;

    @Before
    public void setUp() throws Exception {
        utx.begin();
        em.joinTransaction();
    }

    @After
    public void tearDown() throws Exception {
        utx.rollback();
    }

 [ ... snip ...]
}

If I run my test class (AddressModuleTest, please note that "BaseTest" has a static method annotated with @Deployment for Arquillian) everything is fine and I can read my data from the PostgreSQL database. 如果我运行测试类(AddressModuleTest,请注意,“ BaseTest”有一个以@Deployment for Arquillian注释的静态方法),则一切正常,并且可以从PostgreSQL数据库读取数据。

Unfortunately, If I create a second test class it won't work: 不幸的是,如果我创建第二个测试类,它将无法正常工作:

@RunWith(Arquillian.class)
public class CommunicationModuleTest extends BaseTest {
    @PersistenceContext
    protected EntityManager em;

    @Inject
    protected UserTransaction utx;

    @Before
    public void setUp() throws Exception {
        utx.begin();
        em.joinTransaction();
    }

    @After
    public void tearDown() throws Exception {
        utx.rollback();
    }

    [ ... snip ... ]
}

Maven (respectively surefire) gives me the following error: Maven(分别为surefire)给我以下错误:

Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.758 sec <<< FAILURE!
loadMessageDAO(package.CommunicationModuleTest)  Time elapsed: 0.027 sec  <<< ERROR!
java.lang.RuntimeException: Could not inject members
    at org.jboss.arquillian.testenricher.cdi.CDIInjectionEnricher.injectClass(CDIInjectionEnricher.java:135)
    at org.jboss.arquillian.testenricher.cdi.CDIInjectionEnricher.enrich(CDIInjectionEnricher.java:78)
    at org.jboss.arquillian.test.impl.TestInstanceEnricher.enrich(TestInstanceEnricher.java:52)
    at sun.reflect.GeneratedMethodAccessor67.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[ ... snip ... ]

.. with the following root exception: ..具有以下根例外:

Caused by: org.jboss.weld.exceptions.IllegalArgumentException: WELD-001324 Argument bean must not be null
    at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:678)
    at org.jboss.weld.injection.FieldInjectionPoint.inject(FieldInjectionPoint.java:136)
    at org.jboss.weld.util.Beans.injectBoundFields(Beans.java:686)
    at org.jboss.weld.util.Beans.injectFieldsAndInitializers(Beans.java:695)
    at org.jboss.weld.manager.SimpleInjectionTarget$1.proceed(SimpleInjectionTarget.java:106)
    at org.glassfish.weld.services.InjectionServicesImpl.aroundInject(InjectionServicesImpl.java:134)
    at org.jboss.weld.injection.InjectionContextImpl.run(InjectionContextImpl.java:46)
    at org.jboss.weld.manager.SimpleInjectionTarget.inject(SimpleInjectionTarget.java:102)
    at org.jboss.arquillian.testenricher.cdi.CDIInjectionEnricher.injectNonContextualInstance(CDIInjectionEnricher.java:145)
    at org.jboss.arquillian.testenricher.cdi.CDIInjectionEnricher.injectClass(CDIInjectionEnricher.java:125)
    ... 79 more

I went back to the guide and tried to reproduce my issue with their code - with no sucess (ie they are not affected by my problem). 我回到指南,尝试用他们的代码重现我的问题-没有成功(即他们不受我的问题影响)。 Therefore I assume that either my UserTransaction handling is wrong or it is an issue with my PostgreSQL configuration. 因此,我假设UserTransaction处理错误或PostgreSQL配置存在问题。 I tried different datasources, namely 我尝试了不同的数据源,即

  • org.postgresql.ds.PGSimpleDataSource
  • org.postgresql.ds.PGPoolingDataSource

As well as javax.xa.XADataSource together with org.postgresql.xa.PGXADataSource with no success. 以及javax.xa.XADataSourceorg.postgresql.xa.PGXADataSource没有成功。

Does somebody have a clue what's wrong? 有人知道出什么事了吗? I have to admit that I'm (very) inexperience with different DataSources as well as Transaction Management. 我不得不承认,我(非常)对不同的数据源以及事务管理缺乏经验。


UPDATE 更新

It looks as if the issue is independent of PostgreSQL as it happens on MySQL (MariaDB) as well. 看起来问题似乎独立于PostgreSQL,因为它也发生在MySQL(MariaDB)上。 The stacktrace is the same, so I assume the issue lies within my Transaction Management.. stacktrace是相同的,因此我认为问题出在我的事务管理之内。


Kind regards and many thanks for your help 亲切的问候,非常感谢您的帮助

stupidSheep 笨羊

This bug was introduced by ARQ-1071 in 1.0.4.Final and persists in current version (1.1.1.Final). 此错误由ARQ-1071在1.0.4.Final中引入,并在当前版本(1.1.1.Final)中仍然存在。 The reason is that all ThreadLocal occurences were replaced by InheritableThreadLocal to fix a NPE on @Timeout usages. 原因是所有ThreadLocal事件都被InheritableThreadLocal取代,以在@Timeout用法上修复NPE。

The proposed fix consists on revert just one occurence of InheritableThreadLocal to ThreadLocal like it has been done on following Pull Request: https://github.com/arquillian/arquillian-core/pull/53 提议的修复方法包括将InheritableThreadLocal的仅一种情况还原为ThreadLocal,就像在以下Pull Request中所做的一样: https : //github.com/arquillian/arquillian-core/pull/53

Please, vote on the issue to be released on next 1.1.2.Final version: https://issues.jboss.org/browse/ARQ-1458 请对下一版本1.1.2中发布的问题进行投票。最终版本: https ://issues.jboss.org/browse/ARQ-1458

The commit to solve this issue in 1.0.3.Final was reverted in subsequent versions, and was not until version 1.1.4.Final when it was finally solved. 1.0.3.Final解决此问题的1.0.3.Final已在后续版本中还原,直到版本1.1.4.Final最终解决后才1.1.4.Final

<dependency>
    <groupId>org.jboss.arquillian</groupId>
    <artifactId>arquillian-bom</artifactId>
    <version>1.1.4.Final</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

I have a similar problem (the only difference is that I'm getting the message "WELD-001456 Argument resolvedBean must not be null"). 我有一个类似的问题(唯一的不同是,我收到消息“ WELD-001456 Argument resolveBean不能为null”)。 Resolved beans are stored in an instance of the class org.jboss.weld.manager.BeanManagerImpl that is shared between all tests in micro deployment. 解析的bean存储在org.jboss.weld.manager.BeanManagerImpl类的实例中,该实例在微部署中的所有测试之间共享。 In my case the cause of failure is that when some test finished, its thread is staying bound with old instance of TestRunnerAdaptor that is linked to the already cleaned bean manager (see method org.jboss.weld.manager.BeanManagerImpl.cleanup()). 在我的情况下,失败的原因是当某些测试完成时,其线程与绑定到已清理的bean管理器的TestRunnerAdaptor的旧实例保持绑定(请参见方法org.jboss.weld.manager.BeanManagerImpl.cleanup()) 。 If some test from next micro deployment will use one of such threads it fail. 如果来自下一个微型部署的某些测试将使用此类线程之一,则它将失败。 The problem is related to Arquillian with version > 1.0.3.Final (in new versions field type org.jboss.arquillian.junit.State.lastCreatedRunner is changed from ThreadLocal to InheritableThreadLocal and now method org.jboss.arquillian.junit.State.isLastRunner() always returns false). 该问题与Arquillian版本> 1.0.3.Final有关(在新版本中,字段类型org.jboss.arquillian.junit.State.lastCreatedRunner从ThreadLocal更改为InheritableThreadLocal,现在将方法org.jboss.arquillian.junit.State更改了。 isLastRunner()始终返回false)。

I don't know how to solve this problem. 我不知道如何解决这个问题。 The only way is use Arquillian 1.0.3.Final. 唯一的方法是使用Arquillian 1.0.3.Final。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM