Java EE 6 - Embedded container EJB tests

Dzhu picture Dzhu · Oct 15, 2010 · Viewed 8.4k times · Source

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

Answer

Dzhu picture Dzhu · Oct 15, 2010

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.