EJB 3.1 Embeddable

EJB 3.1 Embeddable prototype

This page reflects the current state of the JBoss EJB 3.1 Embeddable prototype.

 

The JBoss EJB 3.1 Embeddable prototype is not JBoss Embedded or the old EJB 3 Embedded. The old EJB 3 Embedded was actually a preview of what could be achieved with JBoss MicroContainer. It is better to think of it as a preview of JBoss AS 5.0. Later on it was renamed to JBoss Embedded.

 

Meanwhile for JBoss AS 6 a new JBoss Embedded AS implementation has been made, which enables JBoss AS 6 to be booted within a JVM. Using this facility a new standalone prototype has been created.

 

The goal of JBoss EJB 3.1 Embeddable is to have a standalone version of EJB 3 working according to the specifications in EJB 3.1 and fully compatible with the version going into JBoss AS.

How to use in your project

You can use jboss-ejb3-embedded-standalone either from Maven or using the jar directly in your favorite IDE/build/test-runner tool.

Maven

To get access to the latest Embeddable artifacts you must enable the JBoss Maven repositories either in your settings.xml or in your pom.xml. As an example I've pasted a pom.xml here:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.jboss.beach.ejb3</groupId>
   <artifactId>test-embedded</artifactId>
   <name>test-embedded</name>
   <version>0.0.1-SNAPSHOT</version>
   <description/>

   <repositories>
      <repository>
         <id>jboss-public-repository-group</id>
         <name>JBoss Public Maven Repository Group</name>
         <url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url>
         <releases>
            <enabled>true</enabled>
         </releases>
         <snapshots>
            <enabled>true</enabled>
         </snapshots>
      </repository>
   </repositories>

   <build>
      <plugins>
         <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
               <source>1.6</source>
               <target>1.6</target>
            </configuration>
         </plugin>
         <plugin>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>2.6</version>
            <configuration>
               <argLine>-Djboss.home=${JBOSS_HOME} -Xmx512m -XX:MaxPermSize=256m -Djava.endorsed.dirs=${JBOSS_HOME}/lib/endorsed</argLine>
            </configuration>
            <executions>
               <execution>
                  <goals>
                     <goal>integration-test</goal>
                     <goal>verify</goal>
                  </goals>
               </execution>
            </executions>
         </plugin>
      </plugins>
   </build>
   
   <dependencies>
      <dependency>
         <groupId>org.jboss.ejb3.embedded</groupId>
         <artifactId>jboss-ejb3-embedded-standalone</artifactId>
         <version>1.0.0-alpha-2</version>
      </dependency>
      <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>[4,)</version>
         <scope>test</scope>
      </dependency>
   </dependencies>
</project>

Jar usage

The jboss-ejb3-embedded-standalone jar is located in $JBOSS_HOME/client/jboss-ejb3-embedded-standalone.jar. Make sure this jar is on your class path when you run your Embeddable EJB test.

 

Note that the jar has references to other jars via a Class-Path entry in the manifest. So if you copy it around make sure these are copied (or available) as well. The most important one being javassist.jar because of the way we've implement no-interface views.

How to use in your code

Now you can create any kind of session bean in your code and do a test on it using Embeddable.

public class HelloBeanITCase
{
   @Test
   public void test1() throws NamingException
   {
      EJBContainer container = EJBContainer.createEJBContainer();

      // Note that global naming isn't working yet.
      InitialContext ctx = new InitialContext();
      Hello bean = (Hello) ctx.lookup("HelloBean/local");

      String now = new Date().toString();
      String actual = bean.sayHello(now);

      assertEquals("Hello " + now, actual);

      container.close();
   }
}


The test above is actually defined as an (Maven) integration test. This is because of the finacle details in class loading of the surefire plugin. So we'll use the failsafe plugin instead.

How to run your test

To run your test you need to have a full JBoss AS installation at hand. The standalone embeddable will delegate to JBoss Embedded AS to boot up an AS instance in your JVM.

 

  1. Make sure either your environment variable JBOSS_HOME or system property jboss.home is setup properly.
  2. Use the following command line '-Xmx512m -XX:MaxPermSize=256m -Djava.endorsed.dirs=$JBOSS_HOME/lib/endorsed'.

 

The pom.xml shown previously outlines how this can be achieved using the failsafe plugin. Surefire plugin does class loading trickery to get stuff up and running. This conflicts with the way Embedded works.

Common Problems

  1. OutOfMemoryError or empty Exception from main thread.
    Because we run the full AS within a JVM you need extra memory. There might even not be enough memory for a proper stack trace.
    Add '-Xmx512m -XX:MaxPermSize=256m' to your command line.
  2. java.lang.NoSuchMethodError: javax.annotation.Resource.lookup()Ljava/lang/String;
    The current JDK comes with an older version of the Common Annotations API (JSR 250). The correct version is distributed with the AS installation. This is controlled with system property java.endorsed.dirs, which is not pointing to $JBOSS_HOME/lib/endorsed. (Note: Intellij has no environment variables replacing, best use full path.)
    Add '-Djava.endorsed.dirs=$JBOSS_HOME/lib/endorsed' to your command line.
  3. Extremely slow startup and running of Embedded AS when using JDK logging.
    The JDK logging implementation is extremely slow, so jboss-ejb3-embeddable-standalone overrides this to use JBoss LogManager. This conflicts when you're using logging as well. The solution is to add jboss-logmanager to your class path (/project dependencies) and set '-Djava.util.logging.manager=org.jboss.logmanager.LogManager'. This also requires a proper logging configuration file.

Source

The source for all code used in this article can be found on GitHub, https://github.com/wolfc/jboss-beach-ejb3-embedded.

Questions

Please direct any questions to the EJB 3 space.