Testing a JavaEE Application with OpenEJB and TomEE


Testing your application in your build is mandatory today. Not doing it simply means you don’t know what you’ll provide. That’s why libraries like arquillian are born. However openejb always thought of it and the goal of this post is to share different ways to test an application with OpenEJB and TomEE.

ApplicationComposer or build your application yourself

ApplicationComposer is a JUnit runner provided by OpenEJB. It was designed to ease OpenEJB internal tests but it is as usable as any other framework. The idea is to give the container configuration and skip the discovering part.

You need to provide at least one module to deploy (ejbmodule, persistence module, …). However, you can add some more modules, some configuration, …

Then simply use you test class as a managed bean : injections are available!

Finally, write your tests using injections.

Ready to try ?

If you are using maven let’s add the following dependency :

<dependency>
  <groupId>org.apache.openejb</groupId>
  <artifactId>openejb-core</artifactId>
  <version>4.0.0</version>
  <scope>test</scope>
</dependency>

Then define your module:

@Module // here a single bean
public SingletonBean app() throws Exception {
    final SingletonBean bean = new SingletonBean(Persister.class);
    bean.setLocalBean(new Empty());
    return bean;
}

@Module // a more complicated example
public EjbModule app() throws Exception {
    final StatelessBean bean = new StatelessBean(AppJpaDAO.class);
    bean.setLocalBean(new Empty());

    final StatelessBean test = new StatelessBean(AppCDI.class);
    bean.setLocalBean(new Empty());

    final EjbJar ejbJar = new EjbJar();
    ejbJar.addEnterpriseBean(bean);
    ejbJar.addEnterpriseBean(test);

    final Beans beans = new Beans();
    beans.addManagedClass(PlcBaseDAO.class);
    beans.addManagedClass(PlcBaseJpaDAO.class);

    final EjbModule jar = new EjbModule(ejbJar);
    jar.setBeans(beans);

    return jar;
}

@Module // a persistence.xml
public Persistence persistence() {
   final PersistenceUnit unit = new PersistenceUnit("my-unit");
   unit.addClass(Something.class);
   unit.setProperty("openjpa.RuntimeUnenhancedClasses", "supported");
   unit.setProperty("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true)");
   unit.setExcludeUnlistedClasses(true);

   final Persistence persistence = new Persistence(unit);
   persistence.setVersion("2.0");
   return persistence;
}

If you need some particular configuration you can provide additional properties (to define any resource such as a datasource, a connection factory, …) :

@Configuration
public Properties config() {
    final Properties p = new Properties();
    p.put("my-db", "new://Resource?type=DataSource");
    p.put("my-db.JdbcDriver", "org.hsqldb.jdbcDriver");
    p.put("my-db.JdbcUrl", "jdbc:hsqldb:mem:bval");
    return p;
}

Then simply inject your beans and write your tests:

@RunWith(ApplicationComposer.class)
public class MyTest {
@EJB
private AppJpaDAO dao;

    @Test
    public void coolTest() {
        dao.someDaoWork();
    }

    [...]

On the example page of OpenEJB website, you’ll find more information about this feature: application-composer

EJBContainer or the standard JEE solution

The JEE6 specification defined the EJBContainer API. It is common to start programmatically a container specifying the application you want to deploy. OpenEJB implementation supports to deploy from the classpath. This feature is really useful for testing an application. Moreover, there is a hook that lets you easily inject beans and resources into the test class.

Here, the idea is to simply define 3 hooks : start of the container, shutdown of the container and injection :

@BeforeClass
public static void start() {
    container = EJBContainer.createEJBContainer();
}

@Before
public void inject() throws NamingException {
    container.getContext().bind("inject", this);
}

@AfterClass
public static void stop() {
    container.close();
}

Then simply write your tests as usual, using injected fields.

Note for maven user: again, only openejb-core is mandatory. For JAX-RS or JAX-WS openejb-cxf-rs or openejb-cxf can be added.

Some more features with the EJBContainer :

  • adding the EJBContainer to properties given to the EJBContainer. PROVIDER property can be set to tomee-embedded to use TomEE instead of OpenEJB (need tomee-embedded dependency)
  • Using OpenEJB and adding openejb-cxf or openejb-cxf-rs (for JAX-WS or JAX-RS) you can set EJBContainer.APP_NAME to an url like name “webapp-name/” (don’t forget to add openejb.embedded.remotable=true for remote features). If not done, the module name will be used (if you use maven, the default is the folder name of the artifact).

A sample of this can be found here: rest-on-ejb or design-by-contract

OpenEJB JUnit Runner or the pre-arquillian way

Before Arquillian era, OpenEJB provided (ans still provides) a runner. It lets you do the same thing, such as the previous example, but without being aware of the container management.

Here is the mandatory dependency:

<dependency>
  <groupId>org.apache.openejb</groupId>
  <artifactId>openejb-junit</artifactId>
  <version>4.0.0</version>
  <scope>test</scope>
</dependency>

Then add the runner to your test class :

@RunWith(OpenEjbRunner.class)

It will use the classpath to deploy beans.

Several additional features are available:

  • properties/resources configuration: @ContextConfig, @Properties
  • security: @TestSecurity
  • injection of test resources: @TestResource + TestResourceTypes constants
Finally write your tests as before.

Arquillian or the de facto standard for tests

Shrinkwrap and Arquillian are 2 libraries provided by JBoss. It eases integration tests.

The first adapters (the link between any container and arquillian) written by OpenEJB/TomEE community was TomEE ones. It helps us a lot to test TomEE and be efficient when a user rises an issue. But nowdays we are working on an embedded adapter too.

Here the different adapters and a little description to help you choose which one is the best for you (note the xml snippet are arquillian.xml configuration, should just be in the test classpath) :

    • org.apache.openejb:arquillian-tomee-embedded: starts TomEE in embedded mode. The drawback is the classical classloading issues you can have (see arquillian forum) with the advantage of being fast.
<arquillian
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">

       <container qualifier="tomee" default="true">
           <configuration> <!-- -1 means random -->
               <property name="httpPort">-1</property>
               <property name="stopPort">-1</property>
           </configuration>
       </container>
</arquillian>
    • org.apache.openejb:arquillian-tomee-remote: tomee is used remotely, probably the best way to test your application but a bit slower than the embedded mode
<arquillian
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">

       <container qualifier="tomee" default="true">
           <configuration>
               <property name="httpPort">-1</property>
               <property name="stopPort">-1</property>
               <property name="ajpPort">-1</property>
               <property name="version">1.0.0-beta-3-SNAPSHOT</property>
               <property name="dir">target/apache-tomee-remote</property>
               <property name="appWorkingDir">target/arquillian-test-working-dir</property>
           </configuration>
       </container>
</arquillian>
    • org.apache.openejb:arquillian-openejb-container (only on trunk for now): openejb embedded container, the fastest one but doesn’t support all TomEE features
<arquillian
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
  <container qualifier="openejb" default="true">
    <configuration>
      <property name="properties">
         // any openejb properties, resources for instance
      </properties>
    </configuration>
  </container>
</arquillian>

Then simply write your arquillian test as usual ;)

About these ads

3 thoughts on “Testing a JavaEE Application with OpenEJB and TomEE

    • Hi,

      I think you speak about arquillian part so the xml is arquillian.xml ;). This post is still relevant but the arquillian config is quite old compared to what we have on trunk ATM. The goal was more to compare solutions than detailling how to do for each ;). That said i’ll add the file path in the post. thks!

Leave a Reply

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