【问题标题】:Tomcat + CDI + ArquillianTomcat + CDI + Arquillian
【发布时间】:2012-09-08 21:58:53
【问题描述】:

我将 Tomcat 7 与 CDI 一起使用,为此我使用 Knappsack Maven Archetypes 中的 jee6-servlet-minimal-archetype 作为起点。

现在想用 Arquillian 来测试 CDI bean,但是找了好久,也只发现了一些与主题相关的问题。

有人可以指出我在 Tomcat 7 上使用 Arquillian 进行 CDI 测试的工作设置(尤其是正确的 pom.xml 使用)吗?


2012/09/11 编辑: 正如下面评论中所指出的,我认为要解决我的问题,我需要有人帮助我理解整个设置,而不是试图在某个时候解决特定的异常。

那么,pom.xml 和测试类必须是什么样子才能在 tomcat 7 中拥有 CDI bean 并能够使用嵌入式和托管容器中的所有注入机制对其进行测试? (顺便问一下,为什么tomcat 7 没有远程容器适配器了,因为它已经为 6 了?)

我已经尝试过调整tomcat 6 example,但无法使其在tomcat 7上运行。

【问题讨论】:

    标签: maven-3 tomcat7 cdi jboss-arquillian


    【解决方案1】:

    不幸的是,我还没有找到或被告知我的问题的工作示例,但能够提出对我有用的东西,我想在这里展示 - 也许它可以帮助某人,因为我假设这个问题不是一个奇特的问题,也许有人可以查看它并给我一个提示,以防万一有什么不同。

    /pom.xml(可在 eclipse [3.7] 和 tomcat 7 [7.0.30] 中使用,确保项目属性/部署程序集不包含测试类/资源):

    <?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/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.mycompany</groupId>
        <artifactId>cditomcat</artifactId>
        <packaging>war</packaging>
        <version>0.0.1-SNAPSHOT</version>
        <name>cditomcat</name>
        <description>This pom is the base for a project using JSF2+CDI on a tomcat 7 and Arquillian for tests.</description>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
            <!-- Java EE Dependencies -->
            <dependency>
                <groupId>com.sun.xml.ws</groupId>
                <artifactId>jaxws-rt</artifactId>
                <version>2.2.7</version>
            </dependency>
    
            <dependency>
                <groupId>javax.faces</groupId>
                <artifactId>jsf-api</artifactId>
                <version>2.0</version>
                <scope>compile</scope>
            </dependency>
    
            <dependency>
                <groupId>com.sun.faces</groupId>
                <artifactId>jsf-impl</artifactId>
                <version>2.0.2-b10</version>
                <scope>compile</scope>
            </dependency>
    
            <dependency>
                <groupId>javax.validation</groupId>
                <artifactId>validation-api</artifactId>
                <version>1.0.0.GA</version>
                <scope>compile</scope>
            </dependency>
    
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-validator</artifactId>
                <version>4.0.0.GA</version>
                <scope>compile</scope>
            </dependency>
    
            <dependency>
                <groupId>org.jboss.weld.servlet</groupId>
                <artifactId>weld-servlet</artifactId>
                <version>1.1.4.Final</version>
            </dependency>
    
            <!-- Test dependencies -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.10</version>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.jboss.arquillian.junit</groupId>
                <artifactId>arquillian-junit-container</artifactId>
                <version>1.0.0.CR5</version>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.jboss.shrinkwrap.container</groupId>
                <artifactId>shrinkwrap-container-tomcat-60</artifactId>
                <version>1.0.0-beta-1</version>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.jboss.shrinkwrap</groupId>
                <artifactId>shrinkwrap-api</artifactId>
                <version>1.0.0-cr-1</version>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.jboss.shrinkwrap</groupId>
                <artifactId>shrinkwrap-spi</artifactId>
                <version>1.0.0-cr-1</version>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.jboss.shrinkwrap.descriptors</groupId>
                <artifactId>shrinkwrap-descriptors-api</artifactId>
                <version>1.1.0-beta-1</version>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.jboss.shrinkwrap.descriptors</groupId>
                <artifactId>shrinkwrap-descriptors-impl</artifactId>
                <version>1.1.0-beta-1</version>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.0</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <build>
            <finalName>cditomcat</finalName>
            <testSourceDirectory>src/test/java</testSourceDirectory>
    
            <plugins>
                <!-- Facilitates downloading source and javadoc in Eclipse -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-eclipse-plugin</artifactId>
                    <version>2.8</version>
                    <configuration>
                        <wtpversion>2.0</wtpversion>
                        <downloadSources>true</downloadSources>
                        <downloadJavadocs>true</downloadJavadocs>
                    </configuration>
                </plugin>
    
                <!-- Ensures we are compiling at 1.6 level -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>2.3.2</version>
                    <configuration>
                        <source>1.6</source>
                        <target>1.6</target>
                    </configuration>
                </plugin>
    
                <!-- Tomcat plugin for embedded tomcat -->
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>tomcat-maven-plugin</artifactId>
                    <version>1.1</version>
                    <configuration>
                        <path>/${project.build.finalName}</path>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    
        <profiles>
            <profile>
                <id>tc7-embedded</id>
                <activation>
                    <activeByDefault>true</activeByDefault>
                </activation>
    
                <build>
                    <testResources>
                        <testResource>
                            <directory>src/test/resources</directory>
                        </testResource>
                        <testResource>
                            <directory>src/test/resources/embedded</directory>
                        </testResource>
                    </testResources>
                </build>
    
                <dependencies>
                    <dependency>
                        <groupId>org.jboss.arquillian.container</groupId>
                        <artifactId>arquillian-tomcat-embedded-7</artifactId>
                        <version>1.0.0.CR3</version>
                        <scope>test</scope>
                    </dependency>
    
                    <dependency>
                        <groupId>org.apache.tomcat.embed</groupId>
                        <artifactId>tomcat-embed-core</artifactId>
                        <version>7.0.19</version>
                        <scope>provided</scope>
                    </dependency>
    
                    <dependency>
                        <groupId>org.apache.tomcat.embed</groupId>
                        <artifactId>tomcat-embed-jasper</artifactId>
                        <version>7.0.19</version>
                        <scope>provided</scope>
                    </dependency>
    
                    <dependency>
                        <groupId>org.eclipse.jdt.core.compiler</groupId>
                        <artifactId>ecj</artifactId>
                        <version>3.7</version>
                        <scope>test</scope>
                    </dependency>
    
                    <!-- Provided scoped dependencies for embedded container -->
                    <dependency>
                        <groupId>org.apache.tomcat</groupId>
                        <artifactId>tomcat-catalina</artifactId>
                        <version>7.0.29</version>
                        <scope>provided</scope>
                    </dependency>
    
                    <dependency>
                        <groupId>org.apache.tomcat</groupId>
                        <artifactId>tomcat-coyote</artifactId>
                        <version>7.0.29</version>
                        <scope>provided</scope>
                    </dependency>
    
                    <dependency>
                        <groupId>org.apache.tomcat</groupId>
                        <artifactId>tomcat-jasper</artifactId>
                        <version>7.0.29</version>
                        <scope>provided</scope>
                    </dependency>
    
                    <dependency>
                        <groupId>javax.servlet</groupId>
                        <artifactId>servlet-api</artifactId>
                        <version>2.5</version>
                        <scope>provided</scope>
                    </dependency>
    
                    <dependency>
                        <groupId>org.jboss.arquillian.container</groupId>
                        <artifactId>arquillian-container-test-spi</artifactId>
                        <version>1.0.2.Final</version>
                        <scope>test</scope>
                    </dependency>
    
                    <dependency>
                        <groupId>org.jboss.arquillian.container</groupId>
                        <artifactId>arquillian-container-spi</artifactId>
                        <version>1.0.0.CR5</version>
                        <scope>test</scope>
                    </dependency>
                </dependencies>
            </profile>
    
            <profile>
                <id>tc7-managed</id>
                <build>
                    <testResources>
                        <testResource>
                            <directory>src/test/resources</directory>
                        </testResource>
                        <testResource>
                            <directory>src/test/resources/managed</directory>
                        </testResource>
                    </testResources>
                </build>
    
                <dependencies>
                    <dependency>
                        <groupId>org.jboss.arquillian.container</groupId>
                        <artifactId>arquillian-tomcat-managed-7</artifactId>
                        <version>1.0.0.CR3</version>
                        <scope>test</scope>
                    </dependency>
    
                    <!-- Provided scoped dependencies for embedded container -->
                    <dependency>
                        <groupId>org.apache.tomcat</groupId>
                        <artifactId>tomcat-catalina</artifactId>
                        <version>7.0.29</version>
                        <scope>provided</scope>
                    </dependency>
    
                    <dependency>
                        <groupId>org.apache.tomcat</groupId>
                        <artifactId>tomcat-coyote</artifactId>
                        <version>7.0.29</version>
                        <scope>provided</scope>
                    </dependency>
    
                    <dependency>
                        <groupId>org.apache.tomcat</groupId>
                        <artifactId>tomcat-jasper</artifactId>
                        <version>7.0.29</version>
                        <scope>provided</scope>
                    </dependency>
    
                    <dependency>
                        <groupId>javax.servlet</groupId>
                        <artifactId>servlet-api</artifactId>
                        <version>2.5</version>
                        <scope>provided</scope>
                    </dependency>
    
                    <dependency>
                        <groupId>org.jboss.arquillian.container</groupId>
                        <artifactId>arquillian-container-test-spi</artifactId>
                        <version>1.0.2.Final</version>
                        <scope>test</scope>
                    </dependency>
    
                    <dependency>
                        <groupId>org.jboss.arquillian.container</groupId>
                        <artifactId>arquillian-container-spi</artifactId>
                        <version>1.0.0.CR5</version>
                        <scope>test</scope>
                    </dependency>
                </dependencies>
            </profile>
        </profiles>
    </project>
    

    /src/main/webapp/WEB-INF/web.xml(我还是用2.5版):

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        version="2.5">
        <welcome-file-list>
            <welcome-file>index.html</welcome-file>
        </welcome-file-list>
        <context-param>
            <param-name>facelets.DEVELOPMENT</param-name>
            <param-value>true</param-value>
        </context-param>
        <servlet>
            <servlet-name>Faces Servlet</servlet-name>
            <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>Faces Servlet</servlet-name>
            <url-pattern>*.jsf</url-pattern>
        </servlet-mapping>
        <listener>
            <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
        </listener>
        <resource-env-ref>
            <description>Object factory for the CDI Bean Manager</description>
            <resource-env-ref-name>BeanManager</resource-env-ref-name>
            <resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type>
        </resource-env-ref>
    
    </web-app>
    

    /src/main/webapp/META-INF/context.xml(未使用 Servlet、监听器、过滤器中的注入):

    <?xml version="1.0" encoding="UTF-8"?>
    <Context>
        <!-- disable storage of sessions across restarts -->
        <Manager pathname=""/>
        <Resource name="BeanManager" auth="Container" type="javax.enterprise.inject.spi.BeanManager" factory="org.jboss.weld.resources.ManagerObjectFactory"/>
    </Context>
    

    /src/main/resources/META-INF/beans.xml /src/test/resources/in-container-beans.xml (空标记文件同样用于应用和测试):

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="
          http://java.sun.com/xml/ns/javaee 
          http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
    </beans>
    

    /src/test/resources/in-container-web.xml(嵌入式和托管相同):

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        version="2.5">
    
        <env-entry>
            <env-entry-name>name</env-entry-name>
            <env-entry-type>java.lang.String</env-entry-type>
            <env-entry-value>Tomcat</env-entry-value>
        </env-entry>
    
        <listener>
            <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
        </listener>
    
        <resource-env-ref>
            <resource-env-ref-name>BeanManager</resource-env-ref-name>
            <resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type>
        </resource-env-ref>
    </web-app>
    

    /src/test/resources/in-container-context.xml(嵌入式和托管相同):

    <Context>
        <Resource name="BeanManager" auth="Container"
            type="javax.enterprise.inject.spi.BeanManager" factory="org.jboss.weld.resources.ManagerObjectFactory" />
    </Context>
    

    /src/test/resources/embedded/arquillian.xml(此文件仅用于嵌入):

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <arquillian xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://jboss.org/schema/arquillian"
        xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
    
        <engine>
            <property name="deploymentExportPath">target</property>
        </engine>
        <container qualifier="tomcat" default="true">
            <configuration>
                <property name="tomcatHome">target/tomcat-embedded-7</property>
                <property name="workDir">work</property>
                <property name="appBase">webapps</property>
                <property name="bindHttpPort">8889</property>
                <property name="unpackArchive">true</property>
            </configuration>
        </container>
    </arquillian>
    

    /src/test/resources/managed/arquillian.xml(此文件仅供托管):

    <?xml version="1.0"?>
    <arquillian
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns="http://jboss.org/schema/arquillian"
            xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
    
        <container qualifier="tomcat" default="true">
            <configuration>
                <property name="jmxPort">8099</property>
                <property name="host">localhost</property>
                <property name="port">8080</property>
                <property name="user">tomcat</property>
                <property name="pass">manager</property>
            </configuration>
        </container>
    </arquillian>
    

    要使托管容器部署工作,必须扩展 tomcat 的 tomcat-users.xml 文件以启用管理器,例如:

    ...
    <role rolename="manager-gui" />
        <role rolename="manager-jmx" />
        <role rolename="manager-script" />
        <user username="tomcat" password="manager"
            roles="manager-gui,manager-jmx, manager-script" />
    ...
    

    最后,每个arquillian test class都要有如下部署方式(我用的是Servlet 2.5):

    ...
        @Deployment
        @OverProtocol("Servlet 2.5")
        public static WebArchive createDeployment() {
            return ShrinkWrap
                    .create(WebArchive.class, "test.war")
                    .addClass(MyTest.class)
                    .addAsLibrary(
                            MavenArtifactResolver
                                    .resolve("org.jboss.weld.servlet:weld-servlet:1.1.4.Final"))
                    .addAsWebInfResource("in-container-beans.xml", "beans.xml")
                    .addAsManifestResource("in-container-context.xml",
                            "context.xml").setWebXML("in-container-web.xml");
        }
    ...
    

    Weld 必须被打包,在我的例子中,它取自本地 maven 存储库,正如在问题的引用示例(编辑部分)中通过以下代码完成的那样:

    public class MavenArtifactResolver {
        private static final String LOCAL_MAVEN_REPO =
                System.getProperty("user.home") + File.separatorChar +
                        ".m2" + File.separatorChar + "repository";
    
        public static File resolve(String groupId, String artifactId, String version) {
            return new File(LOCAL_MAVEN_REPO + File.separatorChar +
                    groupId.replace(".", File.separator) + File.separatorChar +
                    artifactId + File.separatorChar +
                    version + File.separatorChar +
                    artifactId + "-" + version + ".jar");
        }
    
        public static File resolve(String qualifiedArtifactId) {
            String[] segments = qualifiedArtifactId.split(":");
            return resolve(segments[0], segments[1], segments[2]);
        }
    }
    

    【讨论】:

      【解决方案2】:

      这是适用于 Java EE 认证版本的 Tomcat 7 (TomEE) 的设置。它包括 CDI 和一些可用的 Arquillian 适配器:

      请注意,该页面提到使用属性来获取正确的端口以用于向 Tomcat 发送请求。忽略那个。正确的方法是在您的测试用例中使用这样的字段:

      @ArquillianResource
      private URL url;
      

      这将是您的 web 应用程序、端口和所有内容的基本 URL。

      【讨论】:

      • 我已经听说过 TomEE,但在我的情况下不会这样做,因为客户的环境已经设置好,我们将在那里有一个普通的 tomcat。但是由于有适用于 tomcat 7 的适配器,包括托管的和嵌入式的,并且由于有适用于 tomcat + CDI 的工作示例,我确实希望这三个都有一个设置 - 只是我还没有找到一个示例。
      • 还有一个适配器版本可以启动普通的 Tomcat 7,部署 OpenWebBeans、OpenEJB 等,然后部署应用程序。您使用的是什么 CDI 实现?
      • 我使用 JBoss 7 附带的 Weld(这是我的首选环境)。
      • 你答案中的链接已经失效了……你知道页面是否被移动了吗?
      【解决方案3】:

      您可以查看 Arquillian 的 Tomcat-7 托管容器的 POM,它添加了 Weld-Servlet 作为测试依赖项。

      Weld JAR 通过 ShrinkWrap Maven 依赖解析器加载到 Arquillian @Deployment defined in the test classes。您还需要在部署中包含一个空的beans.xml 文件。注意 - 虽然没有将 CDI bean 注入到测试类中,但 Weld 用于注入 @Resource

      【讨论】:

      • 感谢您的提示,我尝试调整您指出的项目,但没有成功。我还使用this 文章作为起点,它显示了 tomcat 6 的工作设置,并尝试将其调整为 tomcat 7,但它不起作用。您能指出一些工作示例,或者至少是一个涵盖 tomcat 7 arquillian 适配器和 cdi 的 pom 吗?
      • @Geziefer 您看到什么错误,或者故障在哪里?
      • 问题是,我尝试了不同的事情并得到了不同的异常(ClassNotFound、NoSuchMethod,...),并且我不断添加依赖项,但不知道到底需要什么。所以我担心,如果我发布一个异常,它可能会在这里解决并引导我进入下一个,而不知道我一开始就走错了方向。所以,我扩展了我的问题,请参见上文。
      猜你喜欢
      • 1970-01-01
      • 2017-06-13
      • 2015-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多