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)
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.
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.
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.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With