【问题标题】:CDI: beans.xml not used in an EJB project during integration testing with ArquillianCDI:在使用 Arquillian 进行集成测试期间 EJB 项目中未使用 beans.xml
【发布时间】:2016-09-20 02:13:33
【问题描述】:

我正在尝试使用显式 CDI 创建 Java EE 7 项目。该项目由 Maven 打包为 ejb 项目。

尽管 Java EE 7 不再需要 beans.xml,但我有一个这样的文件,位于 src/main/resources/META-INF/beans.xml 下,因为我想使用 @Alternatives 进行测试。

更准确地说,我想在集成测试期间使用 H2 内存数据库(使用 Arquillian 和 Weld),但对于非本地环境来说,这是一个很好的 ol Postgres 数据库。

我的问题:

beans.xml 文件似乎被忽略了。测试:

  • 当我删除 @Produces EntityManager 的类之一时,它会按预期工作。
  • 如果我有两个类,但只有一个注释 @Alternative,它会使用另一个,不管 beans.xml 说什么。
  • 当我的两个类都带有 @Alternative 注释时,它会失败并显示

org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied 具有限定符 [@Default] 的类型 [EntityManager] 的依赖项 注入点 [[field] @Inject private arquillian.ArquillianTestAbstract.em]

我有点希望beans.xml 出现在错误的地方或其他地方,但我搜索了很远(包括this related question on SO),但找不到我的错误。

一些文件:

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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>
    <parent>
        <groupId>com.mystuff</groupId>
        <artifactId>myparent</artifactId>
        <version>${project-version}</version>
    </parent>
    <artifactId>myproject</artifactId>
    <packaging>ejb</packaging>

(snip - various dependencies)       

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-ejb-plugin</artifactId>
                    <version>${ejb-plugin-version}</version>
                    <configuration>
                        <ejbVersion>${ejb-version}</ejbVersion>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>${surefire-plugin-version}</version>
                    <configuration>
                        <argLine>-Dfile.encoding=UTF-8</argLine>
                        <forkCount>1C</forkCount>
                        <redirectTestOutputToFile>false</redirectTestOutputToFile>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>  
    </build>

</project>

src/main/resources/META-INF/beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       bean-discovery-mode="all" version="1.1"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd">

    <alternatives>
        <class>persistence.TestDatabaseProducer</class>
    </alternatives>

</beans> 

src/main/java/persistence/DatabaseProducerImpl.java:

@Singleton
@Alternative
public class DatabaseProducerImpl implements DatabaseProducer {

    @Produces
    @MyDatabase
    @Override
    public EntityManager createEntityManager() {
        return Persistence.createEntityManagerFactory("primary").createEntityManager();
    }

}

src/main/java/persistence/TestDatabaseProducer.java:

@Singleton
@Alternative
public class TestDatabaseProducer implements DatabaseProducer {

    @Produces
    @InternalDatabase
    @Override
    public EntityManager createEntityManager() {
        return Persistence.createEntityManagerFactory("internal").createEntityManager();
    }

}

【问题讨论】:

  • 这不是使用替代品的正确方法。它们不匹配,因为它们产生了两个不同的合格实体经理。您将需要生产相同的产品。但即便如此,还有其他方法可以解决这个问题,特别是如果您使用的是 arquillian。使用替代方案是硬性要求吗?
  • @JohnAment 不,不强制使用替代品。这似乎是通过 Maven 配置文件进行所有配置的好方法(使用 beans-test.xml 文件与原始文件交换)。将不胜感激有关实体管理器限定符问题的一些细节或其他方法。我可能不完全理解 CDI 的某些方面。 (然而:))

标签: jakarta-ee annotations ejb cdi jboss-arquillian


【解决方案1】:

最后,我找错了方向。 beans.xml 文件没有任何问题,只是在测试期间没有考虑到它。

这是特定于通过 Arquillian 对 Weld 进行的测试,并且由于资产被打包并发送到嵌入式容器的方式。

Arquillian 测试的标准做法鼓励使用 ShrinkWrap 创建部署在 Weld 上的 JavaArchive,如果您不要求,ShrinkWrap 不会启动 beans.xml

这段代码解决了问题:(具体来说,.addAsManifestResource() 调用)

@Deployment
public static JavaArchive createDeployment() {
    final BeansDescriptor beansXml = Descriptors.create(BeansDescriptor.class);

    return ShrinkWrap.create(JavaArchive.class)
        .addPackages(true, "persistence")
        .addAsManifestResource(new StringAsset(beansXml.alternativeClass(TestDatabaseProducer.class).exportAsString()), beansXml.getDescriptorName());
} 

【讨论】:

    猜你喜欢
    • 2015-09-20
    • 1970-01-01
    • 2012-08-22
    • 2014-03-18
    • 1970-01-01
    • 2017-06-13
    • 1970-01-01
    • 1970-01-01
    • 2017-06-27
    相关资源
    最近更新 更多