在嵌入式模式下使用 OpenEJB 进行单元测试的困惑
我开始探索在嵌入式模式下使用 OpenEJB 对我的 EJB3 组件进行单元测试的可能性。起初,我收到类似以下输出的错误
Testsuite: HelloBeanTest
Tests run: 4, Failures: 0, Errors: 4, Time elapsed: 1,779 sec
------------- Standard Output ---------------
Apache OpenEJB 3.1.4 build: 20101112-03:32
http://openejb.apache.org/
------------- ---------------- ---------------
------------- Standard Error -----------------
log4j:WARN No appenders could be found for logger
(org.apache.openejb.resource.activemq.ActiveMQResourceAdapter).
log4j:WARN Please initialize the log4j system properly.
------------- ---------------- ---------------
Testcase: sum took 1,758 sec
Caused an ERROR
Name "HelloBeanLocal" not found.
javax.naming.NameNotFoundException: Name "HelloBeanLocal" not found.
at org.apache.openejb.core.ivm.naming.IvmContext.federate(IvmContext.java:193)
at org.apache.openejb.core.ivm.naming.IvmContext.lookup(IvmContext.java:150)
at
org.apache.openejb.core.ivm.naming.ContextWrapper.lookup(ContextWrapper.java:115)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at HelloBeanTest.bootContainer(Unknown Source)
# ... output is the same for all the rest of the tests
openejb.home 属性被设置为系统属性并指向我的 OpenEJB 安装目录。
HelloBeanTest#bootContainer() 是一个 setUp 方法,它在 JNDI 查找中失败。如下所示。
@Before
public void bootContainer() throws Exception{
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,
"org.apache.openejb.client.LocalInitialContextFactory");
Context context = new InitialContext(props);
hello = (Hello) context.lookup("HelloBeanLocal");
}
在与此类问题苦苦挣扎之后,我开始尝试非嵌入模式下的 OpenEJB,并从其安装目录启动容器并将组件部署为 ejb.jar。部署成功,我开始创建一个独立的 Java 客户端。独立的 Java 客户端还没有完成,但同时我又回到了嵌入式模式下进行测试。
令我惊讶的是,测试突然开始通过。我向组件添加了更多功能并对其进行了测试。一切都很好。以下是该运行的输出。
Testsuite: HelloBeanTest
Tests run: 4, Failures: 0, Errors: 0, Time elapsed: 2,281 sec
------------- Standard Output ---------------
Apache OpenEJB 3.1.4 build: 20101112-03:32
http://openejb.apache.org/
------------- ---------------- ---------------
------------- Standard Error -----------------
log4j:WARN No appenders could be found for logger
(org.apache.openejb.resource.activemq.ActiveMQResourceAdapter).
log4j:WARN Please initialize the log4j system properly.
------------- ---------------- ---------------
Testcase: sum took 2,263 sec
Testcase: hello took 0,001 sec
Testcase: sum2 took 0 sec
Testcase: avg took 0,001 sec
我很高兴地编码和测试,直到它再次崩溃。看来是从 /apps 目录中删除 ejb.jar 导致的。因此,OpenEJB 似乎仍然从安装目录进行 JNDI 查找,但在嵌入模式下运行时使用当前目录来查找实际实现。我得出这个结论是因为部署在 apps/ 目录中的 ejb.jar 并不具有本地版本所具有的所有方法。 (我用 javap 仔细检查了。)只有类签名是相同的。
经过这么长的介绍,现在是提问时间。
- 谁能为这种行为提供任何解释?
- 在测试之前在 apps/ 目录中打包和部署 EJB 是一项简单的任务,但我能否确定即使这样我也在测试正确的实现?
- 这一切都与指向 OpenEJB 安装目录的 openejb.home 属性有关吗?
总而言之,OpenEJB 版本是 Apache OpenEJB 3.1.4 build: 20101112-03:32,这也可以在日志输出中看到。
提前致谢。
I started exploring the possibilities of using OpenEJB in embedded mode for unit-testing my EJB3 components. At first I got errors like the below output
Testsuite: HelloBeanTest
Tests run: 4, Failures: 0, Errors: 4, Time elapsed: 1,779 sec
------------- Standard Output ---------------
Apache OpenEJB 3.1.4 build: 20101112-03:32
http://openejb.apache.org/
------------- ---------------- ---------------
------------- Standard Error -----------------
log4j:WARN No appenders could be found for logger
(org.apache.openejb.resource.activemq.ActiveMQResourceAdapter).
log4j:WARN Please initialize the log4j system properly.
------------- ---------------- ---------------
Testcase: sum took 1,758 sec
Caused an ERROR
Name "HelloBeanLocal" not found.
javax.naming.NameNotFoundException: Name "HelloBeanLocal" not found.
at org.apache.openejb.core.ivm.naming.IvmContext.federate(IvmContext.java:193)
at org.apache.openejb.core.ivm.naming.IvmContext.lookup(IvmContext.java:150)
at
org.apache.openejb.core.ivm.naming.ContextWrapper.lookup(ContextWrapper.java:115)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at HelloBeanTest.bootContainer(Unknown Source)
# ... output is the same for all the rest of the tests
The openejb.home property is set as a system property and points to my OpenEJB installation dir.
The HelloBeanTest#bootContainer() is a setUp method and it fails on the JNDI lookup. Shown below.
@Before
public void bootContainer() throws Exception{
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,
"org.apache.openejb.client.LocalInitialContextFactory");
Context context = new InitialContext(props);
hello = (Hello) context.lookup("HelloBeanLocal");
}
After struggling with problems like this I started to try out OpenEJB in non-embedded mode, and started the container from it's installation directory and deployed the components as an ejb.jar. Deployment was successful and I started creating a stand-alone Java client. The stand-alone Java client is still unfinished, but meanwhile I came back to testing in embedded mode.
To my surprise, the tests suddenly started to pass. I added some more functionality to the component and tests for those. Everything worked just fine. Below is the output for that run.
Testsuite: HelloBeanTest
Tests run: 4, Failures: 0, Errors: 0, Time elapsed: 2,281 sec
------------- Standard Output ---------------
Apache OpenEJB 3.1.4 build: 20101112-03:32
http://openejb.apache.org/
------------- ---------------- ---------------
------------- Standard Error -----------------
log4j:WARN No appenders could be found for logger
(org.apache.openejb.resource.activemq.ActiveMQResourceAdapter).
log4j:WARN Please initialize the log4j system properly.
------------- ---------------- ---------------
Testcase: sum took 2,263 sec
Testcase: hello took 0,001 sec
Testcase: sum2 took 0 sec
Testcase: avg took 0,001 sec
I was happily coding and testing until it broke again. It seems that removing the ejb.jar from /apps directory caused it. So, it seems that OpenEJB does the JNDI lookup still from the installation dir, but uses the current dir to find the actual implementations when running in embedded mode. I made this conclusion as the ejb.jar deployed in apps/ dir does not have all the methods that the local version has. (I double checked with javap.) Only the class signature is the same.
After this very long introduction, it's question time.
- Can anyone provide any explanation for this behaviour?
- Packaging and deploying the EJBs in the apps/ dir before testing is simple task, but can I be sure that even then I am testing the correct implementation?
- Does this all have something to do with the openejb.home property pointing at the OpenEJB installation dir?
For summary, OpenEJB version is Apache OpenEJB 3.1.4 build: 20101112-03:32, which is visible in the log outputs as well.
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
它确实与将
openejb.home
设置为指向安装目录有关。有一个
conf/openejb.xml
文件,其中可能有一个apps/
列为部署所在位置。所有日志输出都发送到logs/
目录,而不是在测试用例的 System.out 中,您可以轻松地读取它。要使用嵌入式 OpenEJB,您不需要任何配置文件、目录或端口。您只需将库包含在项目的类路径中即可。
我要说的第一件事是查看 openejb-examples-3.1.4.zip。可能有两打示例项目都使用 Ant 和 Maven 构建脚本进行设置。只要 OpenEJB 库位于类路径中,所有示例都可以在任何环境中运行。以下是使用示例之一在 Eclipse 中进行单元测试的视频。我建议将
simple-stateless
示例作为最佳起点。It does have something to do with setting the
openejb.home
to point to the installation dir.There's a
conf/openejb.xml
file that likely has aapps/
listed as where deployments live. All the log output went to thelogs/
dir and not in System.out of the test case where you can read it easily.To use OpenEJB embedded you don't need any config files, directories, or ports. You just include the libs in your project's classpath.
First thing I'd say is to check out the openejb-examples-3.1.4.zip. There are maybe two dozen example projects all setup with both Ant and Maven build scripts. All the examples will work in any environment as long as the OpenEJB libraries are in the classpath. Here's a video of using one of the examples to unit test in Eclipse. I recommend the
simple-stateless
example as the best starting point.