开发者

Java EE 6 - Embedded container EJB tests

开发者 https://www.devze.com 2023-01-19 21:42 出处:网络
This questiong is regarding Java EE 6, using glassfish v3 embedded-all. I have a unit test that uses EJBContainer to test my stateless EJB. Problem is I\'m having trouble looking up the EJB (remote)

This questiong is regarding Java EE 6, using glassfish v3 embedded-all.

I have a unit test that uses EJBContainer to test my stateless EJB. Problem is I'm having trouble looking up the EJB (remote) using JNDI:

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 {
...
}

gives the exception:

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开发者_如何学C found

I have tried several JNDI resource paths:

e.g.

java:global/BookServiceEJB

java:global/BookService

even:

java:global/BookShelf-1.0-SNAPSHOT/BookServiceEJB

etc...

nothings works

I do not have any xml deployment files configured, only a persistence.xml in META-INF.

The test is using maven surefire:

mvn clean test

Any help is greatly appreciated!

Note: a full deploy to Glassfish server works (using appclient, and @EJB injection)


After much searching, found the solution that works for me...

You'll have to configure the EJBContainer with the property: EJBContainer.MODULES, and the location where the module classes are (if using maven, 'target/classes').

e.g.

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

If your EJB uses JPA, theres another problem in that you will not be able to define a datasource in the embedded container, so have to use the default ds: 'jdbc/__default'.

so for example my persistence.xml looks like so:

<?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> 

I haven't figured out how to configure the embedded container test to use one DS (jdbc/__default), and my app to use another (e.g. jdbc/booksDS)

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

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

To be honest I don't know why people are bothering with Java EE when solutions like spring is so much simpler...

It has been very frustrating and alot of time wasted... hope this helps.


There's a few items you need to check in order to make sure you can load the bean through the context.lookup avoiding a NamingException.

  1. Make sure you have a bean. This may sound something obvious but I spent a lot of time trying to figure out why I wasn't able to get an instance of my service in the tests. The reason was that I was missing the Stateless annotation.

  2. Add the module when creating the container as @Dzhu pointed out. For maven classes will be target/classes, for maven tests will be target/test-classes.

  3. Something is wrong if you find a message like SEVERE: EJB6005:No EJB modules found in the console. It tells you that there are no Stateless annotated classes

  4. Take a look at the embedded glassfish console! In there you will see the lookup names for your beans. Pay attention to the messages in the format INFO: EJB5181:Portable JNDI names for EJB YourBean: [java:global/classes/YourBean!bean.package.YourBean, java:global/classes/YourBean]. That means you can lookup your bean either by calling context.lookup("java:global/classes/YourBean!bean.package.YourBean") or by the shorter name context.lookup("java:global/classes/YourBean") which can be useful if there's no name collisions.

Hope this helps someone. It would have been really helpful to have had this tips.


I have written a small tutorial on using the embedded glassfish 3.1 container, also addressing the issue for needing a different persistence.xml for tests. Also fixing container crashes with remote interfaces and webservices. You can check it out at http://pschyska.blogspot.com/2011/06/unit-testing-ejb-31-with-netbeans-maven.html

0

精彩评论

暂无评论...
验证码 换一张
取 消