Using the EJBContainer API with or without Maven (but with GlassFish v3)

October 5, 2009 § 8 Comments

2010 update: This blog is still pretty accurate but do note that GlassFish v3 and NetBeans 6.8 have been released in final version

The typical way to start GlassFish is to use $asadmin start-domain but you could also start it using java -jar modules/glassfish.jar. Both start a standalone instance of GlassFish. The following paragraphs discuss GlassFish Embedded (i.e. start it using an API).

There are at least two ways to start GlassFish in embedded mode: using org.glassfish.api.embedded.Server and associated classes but also using the (now standard in EJB 3.1) EJBContainer.createEJBContainer() API. Let me describe here the latter one and reserve the more general embedded case for a later blog entry.

The goal is to write something like as simple as this to test your EJB :


// new in EJB 3.1!
    EJBContainer c = EJBContainer.createEJBContainer();
    Context ic = c.getContext();
    SimpleEjb ejb = (SimpleEjb)
        ic.lookup("java:global/sample/SimpleEjb");
    ejb.sayHello();

EJB’s found in the classpath of the running code above will automatically be deployed and made available via lookups.

Calls to EJBContainer.createEJBContainer() are likely to be made from your tests. If you’re making those calls by constructing yourself the execution classpath, then you simply need to add glassfish/lib/embedded/glassfish-embedded-static-shell.jar, an empty jar with a Class-Path: listing the required jars and that is part of the GlassFish distro. In fact, if you’re using recent builds of NetBeans 6.8 (and the soon-to-be-released beta), the IDE does this for you when GlassFish is the target server. If you are using Maven, it’s a bit trickier.

To use EJBContainer.createEJBContainer() from Maven tests, you’ll need to add the following dependency to your POM (updated to final version of GlassFish v3):


     <groupId>org.glassfish.extras</groupId>
     <artifactId>glassfish-embedded-all</artifactId>
     <version>3.0</version>
     <scope>test</scope>

You could restrict this to a smaller set of GlassFish artifacts but for non-trivial tests (if you use JPA for instance), you would start to have a fairly long list of dependencies so the above sounds like a reasonable thing to do. This will require Maven to download the GlassFish All-in-one JAR file (40MB or so). The reason I wrote it would be trickier with maven is that you need to pass a property during the createEJBContainer() call indicating the location of a GlassFish v3 install. The above Java code would need to read something like this:


     Map p = new HashMap();
     p.put ("org.glassfish.ejb.embedded.glassfish.installation.root",
           "/path/to/glassfish"); // include trailing "/glassfish"
     ec = EJBContainer.createEJBContainer(p);

As of build 69 (maybe 70?), this is no longer needed – i.e. you can simply have glassfish-embedded-all.jar as a dependency or simply in your classpath. A full install of GlassFish is no longer required (although it may be interesting if you want to use JDBC configurations). Read this blog by Thomas for another interesting approach: Nice follow-up blog here: http://ctpjava.blogspot.com/2009/10/unit-testing-ejbs-and-jpa-with.html

Starting the appserver this way (with or without Maven) exercises the actual GlassFish code, not another implementation or a customized fork. There are some limitations to what you can run and in particular port configuration is ignored (not listening on any) and only local EJB interfaces are available (the spec only requires EJB 3.1 lite support). On the other hand, JPA calls are very much possible.

This should all work with v3 promoted build 66 (I just tested this with promoted build 70, see above simplification). Adam Bien beat me to covering that topic, but I hope you get some additional info here. In my case the start-up, setup, deploy and shutdown of GlassFish Embedded are worth about 6 seconds. Note that there is no OSGi involved here.

For a complete working example with JPA calls, check out this sample code.

The EJB 3.1 specification has a chapter (#22) on “Embeddable Usage”. Check it out for further details about EJBContainer.

Update: some people are facing classpath/maven issues that causes the test to fail to find any EJB to test. The above is meant to run with an existing install of GlassFish (sorry this wan’t clear) and this great thread has more data on what the issues can be. Marina describes the expected behavior and Laird goes into details about the use of maven-surefire-plugin and its <forkMode> configuration parameter. Make sure you read this if you have similar issues.

Update 2: per the EJB 3.1 specification EJBContainer is only required to support “EJB light” (no remote interfaces for instance).

About these ads

Tagged: , , , ,

§ 8 Responses to Using the EJBContainer API with or without Maven (but with GlassFish v3)

  • Sean says:

    I’ve followed the instruction exactly using the glassfish3-b66, but I still get the following error in Maven test.
    java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/ejb/embeddable/EJBContainer
    at the line
    EJBContainer ejbC = EJBContainer.createEJBContainer(p);

  • Alexis MP says:

    Sean,
    Can you start a discussion on the GlassFish forum (http://forums.java.net/jive/forum.jspa?forumID=56) or on the USERS mailing list? It’ll be easier than using this comments thread (sharing your pom.xml and full test code might help).

  • Alphy says:

    Hi,
    Great article.It was of great help.I managed to run the testing for my EJB3.1 without maven . I would like to know how to configure a local database which is not my development database or inmemory database for my testing purpose.
    Thanks

  • Alexis MP says:

    Does Thomas’ blog help out in using an existing domain.xml config (which can be configured to use any database) help at all : http://ctpjava.blogspot.com/2009/10/unit-testing-ejbs-and-jpa-with.html ?
    Or maybe I’m mis-understanding the question.

  • Robert Gass says:

    Hi. I’m having a terrible time getting this to work. Here’s what I have in my JUnit test method right now:
    Map p = new HashMap();
    p.put ( "org.glassfish.ejb.embedded.glassfish.installation.root",
    "C:\\\\Program Files\\\\sges-v3\\\\glassfish"); // add the (p)
    EJBContainer ec = EJBContainer.createEJBContainer();
    Here’s what I have in my pom.xml
    <dependency>
    <groupId>org.glassfish.extras</groupId>
    <artifactId>glassfish-embedded-all</artifactId>
    <version>3.0-b70</version>
    <scope>test</scope>
    </dependency>
    <dependency>
    <groupId>embedded</groupId>
    <artifactId>glassfish-embedded-static-shell</artifactId>
    <version>1.0</version>
    <scope>system</scope>
    <systemPath>C:\\Program Files\\sges-v3\\glassfish\\lib\\embedded\\glassfish-embedded-static-shell.jar</systemPath>
    </dependency>
    Both depedancies are resolved properly. However, I get this error:
    No EJBContainer provider available The following providers: org.glassfish.ejb.embedded.EJBContainerProviderImpl Returned null from createEJBContainer call.
    \*I can’t copy paste from NetBeans Test Results window to give you the full stack.. grrr\*
    I’ve tried numerous incantations, with just the system jar, or the repository jar, with and without the Map parameters. All give the same results.

  • Alexis MP says:

    @Robert, Can you try with the latest "3.0-b74b" version of ‘glassfish-embedded-all’ (this is v3 final).
    Have you tried running your test straight with junit (no Maven) with glassfish-embedded-static-shell.jar in the classpath?
    Could we move this discussion to USERS @ glassfish.dev.java.net? Easier for multiple reasons.

What’s this?

You are currently reading Using the EJBContainer API with or without Maven (but with GlassFish v3) at Bistro! 2.0.

meta

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: