Java EE 6 - 嵌入式容器EJB测试

时间:2010-10-14 23:20:42

标签: java-ee jndi java-ee-6 glassfish-3 glassfish-embedded

这个问题是关于 Java EE 6 ,使用 glassfish v3 embedded-all

我有一个单元测试,它使用EJBContainer来测试我的无状态EJB。问题是我在使用JNDI查找EJB(远程)时遇到问题:

setup() {

  ctx = EJBContainer.createEJBContainer().getContext();

}

...

test() {

BookService bookService = (BookService)ctx.lookup("java:global/BookServiceEJB!com.something.service.BookService");

...

}

@Stateless
public class BookServiceEJB implements BookService {
...
}

@Remote
public interface BookService {
...
}

给出例外:

javax.naming.NamingException: Lookup failed for 'java:global/BookServiceEJB!com.something.service.BookService' in SerialContext  [Root exception is javax.naming.NameNotFoundException: BookServiceEJB!com.something.service.BookService not found]

...

caused by: javax.naming.NameNotFoundException: BookServiceEJB!com.something.service.BookService not found

我尝试了几个JNDI资源路径:

e.g。

java:global/BookServiceEJB

java:global/BookService

甚至:

java:global/BookShelf-1.0-SNAPSHOT/BookServiceEJB

等...

nothings的作品

没有配置任何xml部署文件,只有META-INF中的persistence.xml

测试使用的是maven surefire:

mvn clean test

非常感谢任何帮助!

注意:对Glassfish服务器的完全部署工作(使用appclient和@EJB注入)

3 个答案:

答案 0 :(得分:6)

经过多次搜索,找到了适合我的解决方案......

您必须使用以下属性配置EJBContainer:EJBContainer.MODULES,以及模块类所在的位置(如果使用maven,'target / classes')。

e.g。

...
props = new Properties();
props.put(EJBContainer.MODULES, new File("target/classes"));
ec = EJBContainer.createEJBContainer(props);
...

如果您的EJB使用JPA,则另一个问题是您将无法在嵌入式容器中定义数据源,因此必须使用默认的ds:'jdbc / __ default'。

所以例如我的persistence.xml看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    version="1.0">

    <persistence-unit name="bookshelf" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <class>com.blah.domain.Book</class>
        <jta-data-source>jdbc/__default</jta-data-source>
        <properties>
            <property name="eclipselink.logging.level" value="INFO"/>
        </properties>
    </persistence-unit>

</persistence> 

我还没想出如何配置嵌入式容器测试以使用一个DS(jdbc / __默认值),以及我的应用程序使用另一个(例如jdbc / booksDS)

参见http://www.mentby.com/glassfish/embedded-testing-woes.html

参见http://forums.java.net/jive/thread.jspa?messageID=395759

说实话,我不知道为什么人们在使用Java EE时会遇到麻烦,因为像春天这样的解决方案要简单得多......

这非常令人沮丧,浪费了很多时间......希望这会有所帮助。

答案 1 :(得分:3)

您需要检查一些项目,以确保您可以通过 context.lookup 加载bean,避免 NamingException

  1. 确保你有一个豆子。这可能听起来很明显,但我花了很多时间试图弄清楚为什么我无法在测试中获得我的服务实例。原因是我错过了无状态注释。

  2. 在创建容器时添加模块,如@Dzhu指出的那样。对于maven 目标/ ,对于maven 测试目标/ 测试的类

  3. 如果在控制台中找到SEVERE: EJB6005:No EJB modules found之类的消息,则会出现问题。它告诉您没有无状态注释类

  4. 看看嵌入式glassfish控制台!在那里,您将看到bean的查找名称。请注意INFO: EJB5181:Portable JNDI names for EJB YourBean: [java:global/classes/YourBean!bean.package.YourBean, java:global/classes/YourBean]格式的邮件。这意味着您可以通过调用context.lookup("java:global/classes/YourBean!bean.package.YourBean")或更短的名称context.lookup("java:global/classes/YourBean")来查找您的bean,如果没有名称冲突,这可能很有用。

  5. 希望这有助于某人。有这个提示会非常有帮助。

答案 2 :(得分:2)

我编写了一个关于使用嵌入式glassfish 3.1容器的小教程,同时解决了需要不同persistence.xml进行测试的问题。还使用远程接口和Web服务修复容器崩溃。您可以在http://pschyska.blogspot.com/2011/06/unit-testing-ejb-31-with-netbeans-maven.html

查看