在哪里可以找到用于 EJB 测试的完整 Maven Cargo 插件示例?

发布于 2024-08-10 21:22:32 字数 5275 浏览 16 评论 0原文

对于一些小型 JBoss 企业应用程序的测试,我想使用 JUnit 和 Maven Cargo 插件 。 (我知道还有 JSFUnit,但首先我想仔细看看 Cargo。)

网上是否有一个简单的示例,我可以将其用作运行 JUnit 测试的参考,该测试使用 JBoss 调用 EJB 操作(4.2或 5.1) 使用 Maven Cargo 插件?我发现了一些关于配置的很好的介绍,但是我在 EJB 查找中收到错误消息,因此了解应该如何使用它会很有帮助。

这是使用 InitialContext 的测试代码:

public void testEcho() {
   assertEquals("Echo Echo", lookupEchoBeanRemote().Echo("Echo"));
}

private EchoBeanRemote lookupEchoBeanRemote() {
    try {
        Context c = new InitialContext();
        return (EchoBeanRemote) c.lookup("EchoBean/remote");
    } catch (NamingException ne) {
        Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
        throw new RuntimeException(ne);
    }
}

给出了此错误:

testEcho(de.betabeans.Echo2Test)  Time elapsed: 0.885 sec  <<< ERROR!
java.lang.reflect.UndeclaredThrowableException
    at $Proxy3.Echo(Unknown Source)
    at de.betabeans.Echo2Test.testEcho(Echo2Test.java:17)
Caused by: java.security.PrivilegedActionException: java.lang.reflect.InvocationTargetException
    at java.security.AccessController.doPrivileged(Native Method)
    at org.jboss.ejb3.security.client.SecurityActions.createSecurityContext(SecurityActions.java:657)
    at org.jboss.ejb3.security.client.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:59)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
    at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:74)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
    at org.jboss.aspects.remoting.PojiProxy.invoke(PojiProxy.java:62)
    at $Proxy4.invoke(Unknown Source)
    at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:207)
    at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:164)
    ... 28 more
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at org.jboss.security.SecurityContextFactory.createSecurityContext(SecurityContextFactory.java:117)
    at org.jboss.security.SecurityContextFactory.createSecurityContext(SecurityContextFactory.java:76)
    at org.jboss.ejb3.security.client.SecurityActions$1.run(SecurityActions.java:662)
    ... 38 more
Caused by: java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/security/jacc/PolicyContextException
    at java.lang.ClassLoader.defineClass1(Native Method)

如果我使用 EJB 注释

@EJB(beanInterface=EchoBeanRemote.class,mappedName="EchoBean/remote")
private EchoBeanRemote newSessionBean;

public Echo3Test(String testName) {
    super(testName);
}

public void testEcho() {
   assertEquals("Echo Echo", newSessionBean.Echo("Echo"));
}

测试结果是

testEcho(de.betabeans.Echo3Test)  Time elapsed: 0.001 sec  <<< ERROR!
java.lang.NullPointerException
    at de.betabeans.Echo3Test.testEcho(Echo3Test.java:20)

jndi.properties 位于 EJB jar 根文件夹中并包含这些行:

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=jnp://localhost:1099
### The TimedSocketFactory connection timeout in milliseconds (0 == blocking) 
jnp.timeout=0
### The TimedSocketFactory read timeout in milliseconds (0 == blocking) 
jnp.sotimeout=0

The bean source code is

package de.betabeans;

import javax.ejb.Remote;

@Remote
public interface EchoBeanRemote {
    String Echo(final String in);
}
package de.betabeans;

import javax.ejb.Stateless;

@Stateless
public class EchoBean implements EchoBeanRemote {
    public String Echo(final String in) {
        return in + " " + in;
    }
}

我还测试了一个 web可以毫无问题地调用 EJB 的应用程序 - 两种方式,使用 InitialContext 或注释。我在部署 Web 应用程序时收到的警告是

WARN [MappedReferenceMetaDataResolverDeployer] JBossWebMetaData 中存在未解析的引用:[#web-app:AnnotatedEJBReferenceMetaData{name=de.betabeans.Echo3Servlet/echoBean,ejb-ref-type=null,link =null,ignore-dependecy=false,mapped/jndi-name=EchoBean/remote,resolved-jndi-name=null,beanInterface=interface de.betabeans.EchoBeanRemote},#web-app:AnnotatedEJBReferenceMetaData{name=NewServlet/newSessionBean, ejb-ref-type=null,link=null,ignore-dependecy=false,mapped/jndi-name=NewSessionBean/remote,resolved-jndi-name=null,beanInterface=interface de.betabeans.NewSessionBeanRemote}] 12:26:11,770 INFO

所有测试均在两个不同的构建系统上使用 JBoss 5.1.0.GA 执行。

我现在已将完整的 Maven 项目上传到 http://www.mikejustin.com /download/JBossSimpleEJBApp-ejb-test.zip

For tests of some small JBoss enterprise apps I would like to use JUnit, and the Maven Cargo plugin. (I know that there is also JSFUnit but first I would like to take a closer look at Cargo.)

Is there a simple example available online which I could use as a reference for running a JUnit test which invokes a EJB operation using JBoss (4.2 or 5.1) using the Maven Cargo plugin? I have found some good introductions to the configuration, but I get error messages in the EJB lookup so it would be helpful to see how it should be used.

Here is the test code using InitialContext:

public void testEcho() {
   assertEquals("Echo Echo", lookupEchoBeanRemote().Echo("Echo"));
}

private EchoBeanRemote lookupEchoBeanRemote() {
    try {
        Context c = new InitialContext();
        return (EchoBeanRemote) c.lookup("EchoBean/remote");
    } catch (NamingException ne) {
        Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
        throw new RuntimeException(ne);
    }
}

Which gives this error:

testEcho(de.betabeans.Echo2Test)  Time elapsed: 0.885 sec  <<< ERROR!
java.lang.reflect.UndeclaredThrowableException
    at $Proxy3.Echo(Unknown Source)
    at de.betabeans.Echo2Test.testEcho(Echo2Test.java:17)
Caused by: java.security.PrivilegedActionException: java.lang.reflect.InvocationTargetException
    at java.security.AccessController.doPrivileged(Native Method)
    at org.jboss.ejb3.security.client.SecurityActions.createSecurityContext(SecurityActions.java:657)
    at org.jboss.ejb3.security.client.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:59)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
    at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:74)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
    at org.jboss.aspects.remoting.PojiProxy.invoke(PojiProxy.java:62)
    at $Proxy4.invoke(Unknown Source)
    at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:207)
    at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:164)
    ... 28 more
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at org.jboss.security.SecurityContextFactory.createSecurityContext(SecurityContextFactory.java:117)
    at org.jboss.security.SecurityContextFactory.createSecurityContext(SecurityContextFactory.java:76)
    at org.jboss.ejb3.security.client.SecurityActions$1.run(SecurityActions.java:662)
    ... 38 more
Caused by: java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/security/jacc/PolicyContextException
    at java.lang.ClassLoader.defineClass1(Native Method)

If I use the EJB annotation

@EJB(beanInterface=EchoBeanRemote.class,mappedName="EchoBean/remote")
private EchoBeanRemote newSessionBean;

public Echo3Test(String testName) {
    super(testName);
}

public void testEcho() {
   assertEquals("Echo Echo", newSessionBean.Echo("Echo"));
}

The test result is

testEcho(de.betabeans.Echo3Test)  Time elapsed: 0.001 sec  <<< ERROR!
java.lang.NullPointerException
    at de.betabeans.Echo3Test.testEcho(Echo3Test.java:20)

jndi.properties is located in the EJB jar root folder and contains these lines:

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=jnp://localhost:1099
### The TimedSocketFactory connection timeout in milliseconds (0 == blocking) 
jnp.timeout=0
### The TimedSocketFactory read timeout in milliseconds (0 == blocking) 
jnp.sotimeout=0

The bean source code is

package de.betabeans;

import javax.ejb.Remote;

@Remote
public interface EchoBeanRemote {
    String Echo(final String in);
}
package de.betabeans;

import javax.ejb.Stateless;

@Stateless
public class EchoBean implements EchoBeanRemote {
    public String Echo(final String in) {
        return in + " " + in;
    }
}

I have also tested a web application which can call the EJB without problems - in both ways, with InitialContext or an annotation. A warning which I received in the deployment of the web application was

WARN [MappedReferenceMetaDataResolverDeployer] Unresolved references exist in JBossWebMetaData:[#web-app:AnnotatedEJBReferenceMetaData{name=de.betabeans.Echo3Servlet/echoBean,ejb-ref-type=null,link=null,ignore-dependecy=false,mapped/jndi-name=EchoBean/remote,resolved-jndi-name=null,beanInterface=interface de.betabeans.EchoBeanRemote}, #web-app:AnnotatedEJBReferenceMetaData{name=NewServlet/newSessionBean,ejb-ref-type=null,link=null,ignore-dependecy=false,mapped/jndi-name=NewSessionBean/remote,resolved-jndi-name=null,beanInterface=interface de.betabeans.NewSessionBeanRemote}]
12:26:11,770 INFO

All tests performed with JBoss 5.1.0.GA on two different build systems.

I have uploaded the complete Maven project now to http://www.mikejustin.com/download/JBossSimpleEJBApp-ejb-test.zip

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

自由如风 2024-08-17 21:22:32

编辑:添加源后

首先 - 我的示例适用于 JBoss 4.2.3.GA 和 Cargo 1.0
我对您的代码进行了一些重构:

pom.xml 文件

    <groupId>de.betabeans</groupId>
    <artifactId>JBossSimpleEJBApp-ejb-test</artifactId>
    <packaging>ejb</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>JBossSimpleEJBApp-ejb JEE5 EJB Test</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
              <groupId>javax.ejb</groupId>
              <artifactId>ejb-api</artifactId>
              <version>3.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>jboss</groupId>
            <artifactId>jboss-ejb3</artifactId>
            <version>4.2.3.GA</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.client</groupId>
            <artifactId>jbossall-client</artifactId>
            <version>4.2.3.GA</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <repositories>
            <repository>
                <releases>
                    <enabled>true</enabled>
                </releases>
                <snapshots>
                   <enabled>true</enabled>
                    <updatePolicy>always</updatePolicy>
                </snapshots>
                <id>repository.jboss.com</id>
                <name>Jboss Repository for Maven</name>
                <url>http://repository.jboss.com/maven2/</url>
                <layout>default</layout>
            </repository>
    </repositories>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-ejb-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <ejbVersion>3.0</ejbVersion>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.cargo</groupId>
                <artifactId>cargo-maven2-plugin</artifactId>
                <version>1.0</version>
                <configuration>
                    <container>
                        <containerId>jboss42x</containerId>
                        <home>${jboss.home}</home>
                        <append>false</append>
                    </container>
                    <configuration>
                        <type>existing</type>
                        <home>${jboss.home}/server/default</home>
                        <properties>
                            <cargo.jboss.configuration>default</cargo.jboss.configuration>
                            <cargo.rmi.port>1099</cargo.rmi.port>
                            <cargo.logging>high</cargo.logging>
                        </properties>
                    </configuration>
                    <wait>false</wait>
                </configuration>
                <executions>
                    <execution>
                        <id>start-container</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>start</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>stop-container</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>stop</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>surefire-it</id>
                        <phase>integration-test</phase>
                        <goals>
                            <goal>test</goal>
                        </goals>
                        <configuration>
                            <skip>false</skip>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <finalName>JBossSimpleEJBApp-ejb-test</finalName>
    </build>

我在以下部分中更改了您的 pom:

  • 依赖项(您使用来自 glasfish 的 ejb-api)
  • 存储库(我建议在布局默认中使用 JBoss Maven2 )
  • cargo-maven2-plugin 的版本和containerId

我已将资源文件夹移动到测试文件夹

jndi.properties 文件必须由测试(而不是bean)使用,并且可以作为以下或您拥有:

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost

不需要其他配置文件(jboss.xml、MANIFEST.MF)。

服务器配置
jboss 4.2.3.GA 服务器和 ejb.jar 文件的最大问题是它默认不工作!您可以在此处找到问题的描述和解决方法。 (这是最难的事情。在 Jboss 5.0 服务器中,这个问题不存在,但在 maven-cargo-plugin 中,这个容器是实验性的)

就这样
下面我粘贴了一些参考链接,如果您仍然遇到问题,我会将我的整个修复项目发送给您。


My original answer
There are several problems with Cargo and JBoss. Main reason is that datasource configuration in pom doesn't work, so you need to deploy separate datasource file. From JBoss perspective it has to be a file placed in main deploy directory (for Tomcat is located in META-INF folder). Second task is copy jdbc library before cargo run.

Carlos Sanchez 博客 发布的这篇文章对您来说是很好的资源。也许您也可以使用 Selenium 而不是 JSFUnit :)

要复制数据源文件,我使用以下配置:

<前><代码> <插件>
org.apache.maven.plugins
maven-resources-plugin;
<处决>
<执行>
复制 ds-context
<目标>
<目标>复制资源

<阶段>预集成测试
<配置>
${jboss.deploy-ds.dir}
<资源>
<资源>
<目录>${basedir}/src/main/webresources/META-INF
<过滤>true
<包括>
<包括>context-ds.xml






EDIT: after added sources

First of all - my example works on JBoss 4.2.3.GA and Cargo 1.0
I did some refactoring of your code:

pom.xml file

    <groupId>de.betabeans</groupId>
    <artifactId>JBossSimpleEJBApp-ejb-test</artifactId>
    <packaging>ejb</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>JBossSimpleEJBApp-ejb JEE5 EJB Test</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
              <groupId>javax.ejb</groupId>
              <artifactId>ejb-api</artifactId>
              <version>3.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>jboss</groupId>
            <artifactId>jboss-ejb3</artifactId>
            <version>4.2.3.GA</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.client</groupId>
            <artifactId>jbossall-client</artifactId>
            <version>4.2.3.GA</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <repositories>
            <repository>
                <releases>
                    <enabled>true</enabled>
                </releases>
                <snapshots>
                   <enabled>true</enabled>
                    <updatePolicy>always</updatePolicy>
                </snapshots>
                <id>repository.jboss.com</id>
                <name>Jboss Repository for Maven</name>
                <url>http://repository.jboss.com/maven2/</url>
                <layout>default</layout>
            </repository>
    </repositories>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-ejb-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <ejbVersion>3.0</ejbVersion>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.cargo</groupId>
                <artifactId>cargo-maven2-plugin</artifactId>
                <version>1.0</version>
                <configuration>
                    <container>
                        <containerId>jboss42x</containerId>
                        <home>${jboss.home}</home>
                        <append>false</append>
                    </container>
                    <configuration>
                        <type>existing</type>
                        <home>${jboss.home}/server/default</home>
                        <properties>
                            <cargo.jboss.configuration>default</cargo.jboss.configuration>
                            <cargo.rmi.port>1099</cargo.rmi.port>
                            <cargo.logging>high</cargo.logging>
                        </properties>
                    </configuration>
                    <wait>false</wait>
                </configuration>
                <executions>
                    <execution>
                        <id>start-container</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>start</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>stop-container</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>stop</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>surefire-it</id>
                        <phase>integration-test</phase>
                        <goals>
                            <goal>test</goal>
                        </goals>
                        <configuration>
                            <skip>false</skip>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <finalName>JBossSimpleEJBApp-ejb-test</finalName>
    </build>

I've changed your pom in following sections:

  • dependecies (you use ejb-api from glasfish)
  • repositories (I recomend to use JBoss Maven2 in layout default)
  • version and containerId of cargo-maven2-plugin

I've moved resources folder to test folder

jndi.properties file must be use by test (not beans) and can be as follows or that you have:

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost

The orher configuration files (jboss.xml, MANIFEST.MF) aren't necessary.

Configuration of server
The biggest problem with jboss 4.2.3.GA server and ejb.jar file is that it doesn't work by default! Description of the problem and workaround you can find here. (That was the hardest thing. In Jboss 5.0 server this problem doesn't exist but in maven-cargo-plugin this container is as experimental one)

That's all
Below I paste some links to references, If you'll have still problems I will send you my entire fixed project.


My original answer
There are several problems with Cargo and JBoss. Main reason is that datasource configuration in pom doesn't work, so you need to deploy separate datasource file. From JBoss perspective it has to be a file placed in main deploy directory (for Tomcat is located in META-INF folder). Second task is copy jdbc library before cargo run.

Great resource for you is this post from Carlos Sanchez blog. Maybe you can use Selenium instead JSFUnit too :)

To copy datasource file I use following configuration:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy-ds-context</id>
                    <goals>
                        <goal>copy-resources</goal>
                    </goals>
                    <phase>pre-integration-test</phase>
                    <configuration>
                        <outputDirectory>${jboss.deploy-ds.dir}</outputDirectory>
                        <resources>
                            <resource>
                                <directory>${basedir}/src/main/webresources/META-INF</directory>
                                <filtering>true</filtering>
                                <includes>
                                    <include>context-ds.xml</include>
                                </includes>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
            </executions>
        </plugin>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文