Java EE + Tomcat = TomEE

Testing TomEE featuring Arquillian


Following on from yesterday’s tutorial, Jonathan Gallimore details how to test your TomEE application with Arquillian

Following on from yesterday’s Getting
Started with TomEE
tutorial, Jonathan Gallimore details how to
test your newly created application, using the JVM testing platform
Arquillian. He’ll also look at the JAX-RS and Webservice features
of TomEE Plus.

Basic EJB test

One of the easiest ways to test an app is
using the Embeddable EJBContainer API. This is pretty
straightforward and is supported by all the Java EE Web Profile
compliant servers. Just make sure that openejb-core is on your
classpath – add it with a test scope, similar to Listing
 if you are using Maven.

Listing 1: pom.xml dependency for




You can then start up the embedded EJB
container in your test using this line of code:

       EJBContainer ejbContainer = EJBContainer.createEJBContainer();

This will start up the EJB container found
on the classpath in memory, and will deploy any EJB beans
available. EJBs can be looked up from the EJBContainer:

       Object object = ejbContainer.getContext().lookup("java:global/application-name/bean-name!interface-class");

We can use this to test the logic in the
session bean using the test in Listing 2

Listing 2 - Example Embedded EJBContainer


public class MoviesTest {

                public void testShouldAddAMovie() throws Exception {
                        EJBContainer ejbContainer = EJBContainer.createEJBContainer();
                        MoviesImpl movies = (MoviesImpl) ejbContainer.getContext().lookup("java:global/moviefun/MoviesBean!org.superbiz.moviefun.MoviesBean");
                        Movie movie = new Movie();
                        movie.setDirector("Michael Bay");
                        movie.setTitle("Bad Boys");

                        Assert.assertEquals(1, movies.count());
                        List<Movie> moviesFound = movies.findByTitle("Bad Boys");

                        Assert.assertEquals(1, moviesFound.size());
                        Assert.assertEquals("Michael Bay", moviesFound.get(0).getDirector());
                        // more assertions




This test will start up OpenEJB in embedded
mode, and deploy all the EJBs on the classpath. It will then
attempt to add a movie, retrieve the full list of movies to ensure
the new movie was added to the database. Finally, once the test is
complete, the test will remove all the movies from the

The EJBContainer API is a standard part of
the Java EE Web Profile specification, so this test should also be
server agnostic – changing the classpath should be all you need to

As an alternative to looking up the session
bean using its global JNDI name, OpenEJB can also inject a
reference into the test, making the test simpler and more readable.
This can be done by creating a private field: @EJB private
MoviesBean movies, and replacing the bean lookup with:

ejbContainer.getContext().bind("inject", this)

This technique also works for injecting CDI
beans, persistence contexts and resources.

Testing the UI

Testing the EJB is all very well, but what
about web frontend? TomEE takes the Embedded EJBContainer API one
step further, and can start a full embedded copy of TomEE inside
the unit test, with a little bit of extra setup. To make use of the
feature, add the tomee-dependency to the classpath. Listing
shows the Maven dependency to add to pom.xml.

Listing 3 - pom.xml adding the
tomee-embedded dependency




In the test itself, add a method to create a
copy of the application in a temporary directory. This should be
like the exploded directory that gets created in the webapps/
directory when TomEE/Tomcat deploys a .war file. Then start the
Embedded EJB container in the same way, but with these additional

  • EJBContainer.APP_NAME – this should be the
    application name, and will determine the URL context for the
  • EJBContainer.PROVIDER – always
    “tomee-embedded”. This tells the container to start a full TomEE
    embedded container.
  • EJBContainer.MODULES – the path to the
    temporary directory where the application should be deployed
    – the port to use for web application.

Using “new ServerSocket(0).getLocalPort()”
is a great way to select a random free port to start TomEE on –
this will allow this test to be run without clashing with TomEE or
any other server you might have running at the time.

The application will now run completely
embedded in the test, exactly as if it were running in a TomEE
server, and can be tested using a framework such as Selenium or
HtmlUnit. Listing 4 shows an example using

Listing 4 - Example embedded
test with HtmlUnit


private static File createWebApp() throws IOException {
                File file = new File(System.getProperty("") + "/tomee-" + Math.random());
                if (!file.mkdirs() && !file.exists()) {
                        throw new RuntimeException("can't create " + file.getAbsolutePath());

                FileUtils.copyDirectory(new File("target/classes"), new File(file, "WEB-INF/classes"));
                FileUtils.copyDirectory(new File("src/main/webapp"), file);

                return file;

        public static void start() throws IOException {         
                webApp = createWebApp();
                Properties p = new Properties();
                p.setProperty(EJBContainer.APP_NAME, "moviefun");
                p.setProperty(EJBContainer.PROVIDER, "tomee-embedded"); // need web feature
                p.setProperty(EJBContainer.MODULES, webApp.getAbsolutePath());
                p.setProperty(EmbeddedTomEEContainer.TOMEE_EJBCONTAINER_HTTP_PORT, String.valueOf(httpPort));
                container = EJBContainer.createEJBContainer(p);


Arquillian test

Of course, no article that covers Java EE
testing would be complete without mentioning Arquillian. Arquillian is a great testing
framework, and provides a number of adapters for different Java EE
servers. Arquillian and its adapters take care of all the heavy
lifting of packaging up your application, starting a server,
deploying your application, running your test and tearing
everything down afterwards, providing a great way of writing tests
that can be run directly from the IDE without needing a
pre-configured server specifically setup. The same test can also be
run across different application servers just by changing your
settings or using a different Maven profile.

The TomEE team develop and maintain their
own adapters for TomEE – we are one of the only servers that does
this, with most other adapters are maintained by the Arquillian
team themselves. The TomEE team are big believers in testing, and
believe that the server should play a big role in making testing as
easy as possible.

We provide two adapters – embedded or
remote, which will either start an instance of TomEE embedded in
the test, or start and deploy to a remote TomEE server

The anatomy of an Arquillian test is quite
straightforward. Listing 5 shows an example.

Listing 5 – Sample Arquillian


        public class MoviesArquillianHtmlUnitTest {
                @Deployment public static WebArchive createDeployment() {

                        Collection<String> dependencies = Arrays.asList(new String[] {

                        File[] libs = Maven.resolver()

                        WebArchive war = ShrinkWrap.create(WebArchive.class, "test.war")
                                .addClasses(Movie.class, MoviesBean.class, MoviesArquillianHtmlUnitTest.class, ActionServlet.class)
                                .addAsResource(new ClassLoaderAsset("META-INF/ejb-jar.xml"), "META-INF/ejb-jar.xml")
                                .addAsResource(new ClassLoaderAsset("META-INF/persistence.xml"), "META-INF/persistence.xml")

                                        "/", Filters.includeAll());

                        return war;

                @EJB private MoviesBean movies;

                private URL deploymentUrl;

                public void testShouldMakeSureWebappIsWorking() throws Exception {
                        WebClient webClient = new WebClient();
                        HtmlPage page = webClient.getPage(deploymentUrl + "/setup.jsp");

                        assertTrue(pageAsText.contains("Wedding Crashers"));
                        // more assertions

                        page = webClient.getPage(deploymentUrl + "/moviefun");



The first part of the test – the
createDeployment method – uses an API called ShrinkWrap to build a .war
file. The great thing here is you can choose what you would like to
be deployed. That might be your whole application, it might be a
single bean, or it might be most of your application, but with some
classes swapped out for dummy implementations. You will also notice
that this example includes the test class itself in the archive as
well. That’s because in this case, the test actually runs on the
server, and transmits the result back to the test runner. That
provides some great advantages, such as being able to inject EJBs
or CDI beans into the test itself as this example shows with the
@EJB private MoviesBean movies line.

The second part of the test class is the
test itself. Here we have used HTML unit to exercise the moviefun
application by executing the setup.jsp page to populate the
database, and then scraping the main page to check that some of the
movies are present. There are a number of different ways you could
test the application. You could use the injected EJB to add or list
the movies, or you could use the drone support that Arquillian
offers to test your application with a tool such as Selenium. For
more information, take a look at the moviefun example in the TomEE
source code repository and the Arquillian homepage.

The line: @ArquillianResource private
URL deploymentUrl
is another great Arquillian feature. This
field will be injected with the URL that the archive is deployed
to. This avoids the need to hardcode “http://localhost:8080/test”
everywhere, and hope that this was the URL the archive got deployed
to. The TomEE Arquillian adapters can also be configured to use a
random available port. This is done by adding properties httpPort
and stopPort to an arquillian.xml file on the classpath, and
setting the value for both to -1, as shown in Listing

Listing 6 – arquillian.xml settings


<container qualifier="tomee" default="true">
                <property name="httpPort">-1</property>
                <property name="stopPort">-1</property>


Remote EJB client

The current EJB does not define any
interface, and so is treated as a “no-interface proxy”. This is can
be convenient in terms of development, as any class annotated with
@Stateless, @Stateful or @Singleton can be treated as an EJB, it
does have the drawback that it can’t be remotely invoked. If we
wanted to make the EJB remoteable, that’s easy, we can just provide
an interface, annotate it with @Remote, and push the business
methods up, as shown in Listing 7.

Listing 7 – Creating a @Remote


        public interface Movies {
                public abstract List<Movie> findRange(String field, String searchTerm, int firstResult, int maxResults);
                public abstract int count(String field, String searchTerm);
                public abstract int countAll();
                public abstract List<Movie> findRangeAll(int firstResult, int maxResults);
                public abstract List<Movie> getMovies();
                public abstract void deleteMovieId(long id);
                public abstract void deleteMovie(Movie movie);
                public abstract void editMovie(Movie movie);
                public abstract void addMovie(Movie movie);
                public abstract Movie find(Long id);


The server also needs to provide a URL for
the client to connect to. This is available in the tomee console
application if it is deployed, or alternatively can a reference to
the org.apache.openejb.server.httpd.ServerServlet servlet can be
added to the web.xml of any application.

The bean can then be invoked remotely by
including the openejb-client jar in the client project, and looking
up the bean using code similar to the code below. Note that HTTP
(HTTPS can also be used) is used at the network transport – this
allows this remoting to take place very easily without the need to
open additional network ports.

Listing 8 shows how to
configure the ServerServlet and an example client.

Listing 8 - Example remote EJB



Client code:
        Properties p = new Properties();
        p.setProperty(Context.INITIAL_CONTEXT_FACTORY, RemoteInitialContextFactory.class.getName());
        p.setProperty(Context.PROVIDER_URL, "http://localhost:8080/moviefun/ejb");
        InitialContext context = new InitialContext(p);
        MoviesRemote movies = (MoviesRemote) context.lookup("java:global/moviefun/Movies");


There is one important point to note here.
When the MovieBean class is changed to extend to extend the Movies
interface we have added a “business interface” to this class, and
it will no longer act as a no-interface proxy. EJBs are only
treated as no-interface proxies by default if no business
interfaces are specified. That means if any injections in your code
where you are using the class name, i.e.:


        private MoviesBean moviesBean;


will no longer work. To resolve this, you
can either use one of the business interfaces to inject the


       private Movies moviesBean


or you can add the @LocalBean annotation to
the bean itself:


        public class MoviesBean implements Movies {


You may wish to consider always using an
interface, or always adding @LocalBean to your EJBs to avoid
potentially breaking your code further down the line.


The plus version of TomEE also provides
support for both EJB and POJO-based webservices using the Apache
CXF library. Exposing the MoviesBean class as a webservice is very
straightforward, simply annotate the bean and an interface using
the @WebService annotation, as shown in Listing

Listing 9 – Annotating an EJB to create a

        public interface Movies {

        @WebService(endpointInterface = "org.superbiz.moviefun.Movies")
        public class MoviesBean implements Movies {

The webservice does not need to be an EJB,
however. You can create any class, implement an interface, and
annotate both with @WebService. In either case, your application
will be searched for @WebService annotations at deployment time,
and all the webservices will be deployed for you automatically.
TomEE also helpfully displays the address to the webservice on the
console output when TomEE is started up: 


INFO: Creating Service {}MoviesBeanService from class org.superbiz.moviefun.Movies

Nov 19, 2012 6:22:07 PM org.apache.cxf.endpoint.ServerImpl initDestination

INFO: Setting the server's publish address to be http://nopath:80

Nov 19, 2012 6:22:07 PM org.apache.openejb.server.webservices.WsService afterApplicationCreated

INFO: Webservice(wsdl=http://localhost:8080/moviefun/webservices/MoviesBean, qname={}MoviesBeanService) --> Ejb(id=MoviesBean)

The WSDL for the service can be accessed by
adding ?wsdl to the end of the URL.


JAX-RS is a popular API for providing
RESTful webservices, and combined with Javascript is a great way of
creating a Rich Internet Application. The TomEE-RS and TomEE Plus
distributions provide JAX-RS support without requiring any extra
setup. Just like webservice support, you can use JAX-RS simply by
annotating your Java classes. To apply this technique to the
MoviesBean class, we can add the @Path annotation specifying the
relative URL that should provide the service, and the @Produces
annotation to specify the type of output that service should

Each method you wish to use through JAX-RS
also needs annotating with the path, any parameters, and the HTTP
verbs that can be used to access that method. The root entity needs
to be annotated with @XmlRootElement as well, as shown in
Listing 10.

Listing 10 – Annotating moviefun for JAX-RS

        @XmlRootElement(name = "movie")
        public class Movie implements Serializable {

        public class MoviesBean {

                public Movie find(@PathParam("id") Long id) {
                        return entityManager.find(Movie.class, id);

Will produce the following JSON if you visit
this URL: http://localhost:8080/moviefun/movies/find/1:




             "director":"David Dobkin",




             "title":"Wedding Crashers",





In conclusion

This two-part article series has shown you
how to get started with TomEE, and how to use a few of the features
available in the Java EE Web Profile and the JAX-RS distributions
of TomEE. Its certainly possible to build applications that run in
Tomcat, and add the various Java EE features that you need, either
to your application, or even to your Tomcat installation. But if
you’re doing this, I would strongly suggest you check out TomEE –
its still the same Tomcat you know and love, but with the extra
Java EE features you’ve been after, and fully Web Profile

Author Bio - 

Jon is an Open Source and
Java EE enthusiast working for Weatherbys Ltd in the UK. As an Open
Source consumer-turned-contributor, Jon has been a committer for
the Apache TomEE and OpenEJB projects for the past four years, and
has worked on a number of different features including the early
Tomcat 7 integration in TomEE, parts of the EJB 3.1 compliance,
TomEE Arquillian adapters and the OpenEJB Eclipse Plugin. When not
grinding away at work by day, and burning the midnight oil on
Apache TomEE at night, Jon enjoys cooking, watching Formula One,
and playing the occasional game of golf.

This article originally
appeared in JAX Magazine TomEE. For that issue and others, click



All Posts by JonathanGallimore

comments powered by Disqus