【问题标题】:Arquillian fails to inject dependencies after the first test classArquillian 在第一个测试类之后无法注入依赖项
【发布时间】:2013-07-22 07:17:36
【问题描述】:

我有一个有点奇怪的问题。 我目前正在使用 Arquillian (1.1.0.Final) 和 Embedded GlassFish (3.1.2.2)。 我使用以下guide 来设置我的小测试项目。 使用集成的 Derby 数据库一切正常。 我的真实应用程序使用 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>

并且我按照上述指南中的描述访问持久性上下文和用户事务:

@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 ...]
}

如果我运行我的测试类(AddressModuleTest,请注意“BaseTest”有一个用 @Deployment for Arquillian 注释的静态方法)一切都很好,我可以从 PostgreSQL 数据库中读取我的数据。

不幸的是,如果我创建第二个测试类,它将无法工作:

@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(分别是肯定的)给我以下错误:

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 ... ]

.. 有以下根异常:

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

我回到指南并尝试用他们的代码重现我的问题 - 没有成功(即他们不受我的问题的影响)。因此,我假设我的 UserTransaction 处理是错误的,或者是我的 PostgreSQL 配置有问题。 我尝试了不同的数据源,即

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

还有javax.xa.XADataSourceorg.postgresql.xa.PGXADataSource都没有成功。

有人知道出了什么问题吗?我不得不承认,我对不同的数据源以及事务管理(非常)缺乏经验。


更新

问题似乎与 PostgreSQL 无关,因为它也发生在 MySQL (MariaDB) 上。堆栈跟踪是相同的,所以我认为问题出在我的事务管理中..


诚挚的问候,非常感谢您的帮助

笨羊

【问题讨论】:

    标签: java jdbc datasource postgresql-9.1 jboss-arquillian


    【解决方案1】:

    此错误由 ARQ-1071 在 1.0.4.Final 中引入,并在当前版本 (1.1.1.Final) 中持续存在。原因是所有 ThreadLocal 出现都被 InheritableThreadLocal 替换,以修复 @Timeout 使用上的 NPE。

    建议的修复包括将 InheritableThreadLocal 的一次出现恢复为 ThreadLocal,就像在以下拉取请求中所做的那样: https://github.com/arquillian/arquillian-core/pull/53

    请对下一个 1.1.2 发布的问题进行投票。最终版本: https://issues.jboss.org/browse/ARQ-1458

    【讨论】:

      【解决方案2】:

      1.0.3.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>
      

      【讨论】:

        【解决方案3】:

        我有一个类似的问题(唯一的区别是我收到消息“WELD-001456 Argument resolvedBean must not be null”)。解析的 bean 存储在 org.jboss.weld.manager.BeanManagerImpl 类的实例中,该实例在微部署中的所有测试之间共享。在我的例子中,失败的原因是当一些测试完成时,它的线程与旧的 TestRunnerAdaptor 实例保持绑定,该实例链接到已经清理的 bean 管理器(参见方法 org.jboss.weld.manager.BeanManagerImpl.cleanup()) .如果来自下一个微部署的某些测试将使用其中一个这样的线程,它就会失败。问题与版本 > 1.0.3.Final 的 Arquillian 有关(在新版本中,字段类型 org.jboss.arquillian.junit.State.lastCreatedRunner 从 ThreadLocal 更改为 InheritableThreadLocal,现在方法 org.jboss.arquillian.junit.State。 isLastRunner() 总是返回 false)。

        我不知道如何解决这个问题。唯一的方法是使用 Arquillian 1.0.3.Final。

        【讨论】:

        • 你好 postiveCoder!感谢您的回答!我将我的版本更改为 Arquillian 1.0.3.Final,现在它可以工作了。我会在 Arquillian 社区 (JBoss) 中询问他们是否可以提供帮助……(请参阅 community.jboss.org/message/830718)如果我知道更多信息,请随时通知您!
        • 在 SO 和 Arquillian 论坛上都没有人知道答案,所以我会接受你的答案,因为它确实为我的问题提供了解决方法 :)
        • 谢谢。似乎只有我们有这个问题。 :)
        • 您好positiveCoder!我“不接受”你的回答,因为 zyc 解决了这个问题(我还没有测试它,因为我目前不在同一个项目上工作)。
        猜你喜欢
        • 1970-01-01
        • 2017-02-10
        • 2021-05-17
        • 1970-01-01
        • 2016-07-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多