Adam Bien's Weblog

Monday Sep 28, 2009

Embedding EJB 3.1 Container Into Your Unit Tests - Boot Time: 5 Seconds

It simpler and faster, than you may think. The following no-interface view EJB 3.1:

@Stateless

public class HelloWorld {

    public String hello(String message){

        return "Echo: " + message;

    }

...is tested with - the following unit test with embeddable EJB 3.1 container: 

public class HelloWorldTest {

  @Test

  public void hello() throws NamingException{

    EJBContainer ejbC = EJBContainer.createEJBContainer();

    Context ctx = ejbC.getContext();

    HelloWorld helloWorld = (HelloWorld) ctx.lookup("java:global/classes/HelloWorld");

    assertNotNull(helloWorld);

    String expected = "duke";

    String hello = helloWorld.hello(expected);

    assertNotNull(hello);

    assertTrue(hello.endsWith(expected));

    ejbC.close();

  }

It was tested with Glassfish v3 b66 - it is important to use at least the build 66. The sample was developed with Netbeans 6.8 daily builds (should work with 6.7.1 as well).

There is absolutely no configuration or classpath changes needed. You will see an exception first - this issue is already reported. It doesn't, however, impact the test. 

The entire test, with booting the container, takes on my machine about 5 seconds. The project [EmbeddableGlassfishEJB31Test] was already checked-in into: http://kenai.com/projects/javaee-patterns/

[See BeanLocator, page 108 in "Real World Java EE Patterns Rethinking Best Practices" book for EJB 3.0 embeddable test practices, and page 111 for testing with transactions]


[my tweets]  Rss My book: Real World Java EE - Rethinking Best Practices

Kommentare:

Thank you Adam. Very useful...waiting for the final release :)

Gesendet von abdrabba yassine am September 28, 2009 at 12:21 PM CEST #

hi,
I get this error, when running on GlassFish v3 (build 65)

No EJBContainer provider available: no provider names had been found.
javax.ejb.EJBException: No EJBContainer provider available: no provider names had been found.
at javax.ejb.embeddable.EJBContainer.reportError(EJBContainer.java:184)
at javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:121)
at javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:78)
at com.abien.business.hello.HelloWorldTest.hello(HelloWorldTest.java:23)

Do you have any ideas ??

Gesendet von abdrabba yassine am September 28, 2009 at 06:27 PM CEST #

@Abdrabba

1. You are right - it is an error :-)
2. Try it with build 66

And - it works?

adam

Gesendet von Adam Bien am September 28, 2009 at 11:03 PM CEST #

I'm just wondering if you still can call such tests UNIT TESTS.

Gesendet von Bartek Majsak am September 29, 2009 at 12:02 AM CEST #

Where does this container come from? I use Maven so I imagine I would need to add a dependency on some EJB container artifact for test scope. I'm wondering how Java SE knows where the container is and how to load it. I imagine the default NetBeans ant project is configured with a dependency on .jar files in the GlassFish V3 installation directory, and I'm not sure how portable that is to a build server. I like to be able to check out my Maven project to any computer on any OS, have it pull down dependencies from our repo, then build.

Do you get transactions? What if you query two different databases within one transaction, is XA supported? I wonder if it is XA or local transactions in the unit testing environment.

I'd like to see some information on unit testing JAX-WS and JAX-RS EJB endpoints. I think SOAP UI might be helpful but I haven't used it yet.

Once I finish reading my current book and one other, I plan to buy your Java EE 6 patterns book! NBDT promo code? :)

Gesendet von Ryan de Laplante am September 29, 2009 at 06:49 AM CEST #

> I wonder if it is XA or local transactions in the unit testing environment.

I meant to say "I wonder if it is JTA or ...."

Gesendet von Ryan de Laplante am September 29, 2009 at 06:51 AM CEST #

If my EJB's inject or look up things from JNDI such as JDBC DataSources, JavaMail Sessions, JCA connectors, etc. how do I test that?

Gesendet von Ryan de Laplante am September 29, 2009 at 06:52 AM CEST #

@Bartek,

"I'm just wondering if you still can call such tests UNIT TESTS."

I would call it integration-unit. "Real" unit tests are rather primitive: http://www.adam-bien.com/roller/abien/entry/unit_testing_ejb_3_1

However you call it - it is useful,

thanks!,

adam

Gesendet von Adam Bien am September 29, 2009 at 08:24 AM CEST #

Of course such setups are useful and indeed this solution looks really promising. Keep up great writing!

Cheers,
Bartek

Gesendet von Bartek am September 29, 2009 at 08:37 PM CEST #

Hi adam,
I tested the example on GlassFish v3 (build 66) and I have the same error I googled and can't find a fix for that. any advice ?

Gesendet von abdrabba yassine am October 02, 2009 at 09:18 AM CEST #

You may find this useful for the Maven and JPA questions: http://blogs.sun.com/alexismp/entry/testing_ejb_3_1_s

Gesendet von Alexis MP am October 05, 2009 at 09:23 PM CEST #

Hi Adam,
Using Netbeans 6.8M1 and glassfish-b66, I'm getting the following error at the line.

EJBContainer ejbC = EJBContainer.createEJBContainer();

java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/ejb/embeddable/EJBContainer

Do you have any idea how to avoid this problem?

Gesendet von Sean am October 09, 2009 at 11:35 AM CEST #

Wurde auch langsam Zeit

Gesendet von Heiko Scherrer am October 12, 2009 at 12:28 AM CEST #

Looks very cool. How does the classpath look like if the container shall be launched from the commandline or an ordinary Ant build, without NetBeans classpath magic?

Gesendet von Karl Peterbauer am October 27, 2009 at 10:31 PM CET #

"java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/ejb/embeddable/EJBContainer"

I also have this issue. And browsing around for a solution does not give me any help. Suggestions?

Gesendet von Rodrigo Hartmann am January 26, 2010 at 09:10 PM CET #

It seems that the "...Absent Code attribute in method ..." error is due to the javaee-api jar being used instead of the real Glassfish implementation. http://forums.java.net/jive/message.jspa?messageID=226931
http://docs.codehaus.org/pages/viewpage.action?pageId=26408

Even if it is scoped as "provided", the test classpath contains "provided". This is somehow logical, but Maven provides no alternatives, as for now.

You may try to put the javaee-api dependency as the last dependency in the pom file. It worked for me, until I ran in a MDB/JMS related problem, but I think that MDB isn't supoprted yet.

Gesendet von Bruno am February 24, 2010 at 04:37 PM CET #

Senden Sie einen Kommentar:
  • HTML Syntax: Ausgeschaltet
Interviews/About
My Recent Book
Java One 2009
CommunityOne East N.Y.C
JavaONE 2008 Interview
Search
...the last 150 posts
...the last 10 comments
greenfire.dev.java.net
Links
my.netbeans.org
Visitors
License