How to test EJB apps with Glassfish embedded container

There are many articles about EJB deploying and testing. But after one of my colleagues spent a week trying to make it work, I decided to write my own. I’ll describe the wrong path first and then correct it.

Let’s say we have a very simple EJB application with a bean and an interface:

Bean1Remote.java

package test2.beans;
@Remote
public interface Bean1Remote
{
int getBeanId();
}

Bean1.java

@Stateless(name = "Bean1")
@Remote(Bean1Remote.class)
public class Bean1 implements Bean1Remote
{
@Override
public int getBeanId() { return 1; }
}

Next thing we should set up is TestNG framework as described in my previous post. And for testing purposes we will also need some Glassfish dependencies. Both StackOverflow and Google search recommend to use static shell library from Glassfish. After all that tweaks build file should look like this:

build.gradle

apply plugin: 'java'
repositories {
mavenCentral()
jcenter()
}
test {
useTestNG()
}
dependencies {
testCompile 'org.testng:testng:6.9.4'
compile 'javax.ejb:javax.ejb-api:3.2'
compile 'org.glassfish.main.extras:glassfish-embedded-static-shell:4.1'
}

Now let’s test our bean. First we need to create EJB container to work with and not forget to close it after all tests have been executed. This is exactly what @BeforeClass and @AfterClass annotations are for:

Bean1Test.java

private EJBContainer container;
private Bean1Remote bean;
@BeforeClass
public void start() throws NamingException
{
container = EJBContainer.createEJBContainer();
final Context context = container.getContext();
bean = (Bean1Remote) context.lookup("java:global/main/Bean1!test2.beans.Bean1Remote");
}
@AfterClass
public void finish()
{
bean = null;
container.close();
}

Note the lookup string, I instantiate remote interface by its JNDI name that can be seen in deploy or test logs.

TestNG will not build the test class with only start and finish methods, so let’s add some actual tests:

@Test
public void testBeanIsNull() throws Exception
{
Assert.assertNotNull(bean);
}
@Test
public void testGetBeanId() throws Exception
{
final int id = bean.getBeanId();
Assert.assertEquals(id, 1);
}

Now run Gradle task ‘:test’. Chances are that you will see this error message: javax.ejb.EJBException: No EJBContainer provider available: no provider names had been found. And here comes the tricky part: to find any clues about this exception is very hard. According to Google and StackOverflow, tests just work with the code above and the most common issue is wrong lookup string.

However, I was lucky to find a very old blog post back from 2009 that pointed me to the right direction. There is another dependency that should be added to the build.gradle, ‘glassfish-embedded-all’. It contains both dependencies we have already used, ‘ejb-api’ and ‘glassfish-static-shell’, so it is safe to delete them. Here’s how build.gradle dependencies section should look:

dependencies {
testCompile 'org.testng:testng:6.9.4'
compile 'org.glassfish.extras:glassfish-embedded-all:3.1.1'
}

Now all EJB providers will be found and unit tests will work.

Advertisements

Published by

Victor Lapin

Software Development Group Leader

One thought on “How to test EJB apps with Glassfish embedded container”

Add a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s