TomEE is a lightweight application server which provides a full JEE Web Profile. It provides following technologies within a simple war container:
- CDI - Apache OpenWebBeans
- EJB - Apache OpenEJB
- JPA - Apache OpenJPA
- JSF - Apache MyFaces
- JSP - Apache Tomcat
- JSTL - Apache Tomcat
- JTA - Apache Geronimo Transaction
- Servlet - Apache Tomcat
- Javamail - Apache Geronimo JavaMail
- Bean Validation - Apache BVal
This means you simply can drop your EJBs into a single war and be done with your applications. The same goes for CDI and Entity Beans, all reachable from a single war.
Now to provide an example of such a configuration I have written a 3 tier helloworld which does the basic things an enterprise application performs.
- Display a UI
- Calls a service layer
- Calls the database
- Peforms authentication
- Uses internationalization
And all from within a simple Maven start.
This blogentry is about this program and a step by step guide through it.
About the program and getting started
To get started with the program download the program from Github via http://www.github.com/werpu/tomeemaven.
Once downloaded simply run the program via mvn install tomee:run and then point your browser to
http://localhost:8080/tomeemaven. The rest is very barebones and basic and self explanatory.
You will be brought to a landing page which loads some data over a service layer from the database. Next is a login page which does basic authentication and then brings you into a restricted area.
Now the program itself is as barebones as it gets, the more interesting part is the setup, which this blog will guide you through.
The barebones maven setup is a simple war file:
Now to the first interesting part, normally you have in a Maven and Tomcat configuration a huge list of dependencies, which your app uses. Our setup has reduced the dependency list to two entries.
As you can see both dependencies are <scope>provided</scope> which means that the app server provides those two.
The more interesting part is the jee-api include which basically just provides the JEE APIs for the code. We only use a subset of those, but for the simplicity of things a full JEE api include should be enough to get you started.
The second include is the hsql db which we use because we start hsql directly in server mode. (Note TomEE comes with hsql included, we do not have to do anything here regarding including it)
The next part is the TomEE Maven Plugin
This basically is our TomEE starter, we de not have to do anything about its configuration. With this entry our mvn clean install tomee:run is possible and our war automatically picked up as application war.
The last part is the compile time instrumentation weaving for OpenJPA which enhances our entities at compile time.
This is basically the entire maven setup.
The folder hierarchy follows a strict Maven setup with small enhancements for the TomEE Maven plugin.
It is as follows:
Following Folders are of interest
- src/main/java The Java sources
- src/main/resources the resources folger hosting the beans and persistence.xml, this folder later will be compiled into the web-inf/classes folder along with the java sources
- src/main/webapp the web application folder
- src/main/tomee hosting the TomEE configuration file overrides (we will come later to this important folder)
The main difference to a standard Maven layout is the src/main/tomee folder.
It currently hosts 2 files:
- and tomee.xml
tomee.xml hosts a new database resource which connects to a locally running HSQL DB Server. Outside of that it is a blank copy of what is provided from the standard TomEE distribution.
tomcat-users.xml is the standard Tomcat UserDatabase Realm but provides one additional user, who is the login user for our secured part.
We will go later into more details regarding both files. The important part about this files is, that they replace the original files during the build process and bundle them into the running TomEE once you issue mvn install tomee:run on the command line.
That way you can override any of the standard settings of TomEE with your custom settings.
The UI layer
Here we use plain JSF as provided by TomEE (in our case Apache MyFaces 2.1.9 which as time of writing is almost the most recent distribution of Apache MyFaces)
The main difference is that we basically use CDI instead of JSF managed beans. Here is an example page controller class implemented as CDI bean.
The main difference here to a standard Tomcat setup is, that we can inject an EJB directly into our managed bean. This is thanks to TomEE.
The EJB can be straightly bundled into the WAR file, no need for EAR and complicated classloader hierarchies.
This brings us directly to our second layer.
The service/DAO layer
We have implemented the Service layer as stateless Session Bean, since we use JPA we will omit separate DAOs in favor of simplicity.
The Service does not do to much it basically just writes to the database in case no data is present otherwise it will read from the database.
This brings us straight to
The database layer
Centralized database connection
The database layer is a little bit more complicated because it needs several configuration files.
First we have to deal with the a centralized managed database connection.
TomEE utilizes a resource entry in tomee.xml to enable the centralized database connection. (Which theoretically can be shared over multiple applications)
Here is our entry:
What is strikingly odd here is, that this is not the same syntax as used in a standard context.xml Tomcat configuration but instead TomEE follows its own syntax which is explained more thoroughly here (I have not yet tested if a context.xml db connection also works, given that there is the web.xml method, I probably never will (see below)).
In our case we connect to a running HSQLDB server which is started with the application automatically (we will come later to that)
The important parts are following
- the Datasource id="MyDataSource"
- the Type being a DataSource: type="DataSource"
- and JtaManaged being true
Web application managed database connections
Now to the second part the persistence.xml. As already discussed we use OpenJPA for persistence, because it already is present in the container. Hibernate or EclipseLink also would be possible by adjusting the pom.xml and removing the OpenJPA implementation and adding the other jars. Following page has an example which exactly does that.
For our persistence.xml we use following entries:
The important parts are following:
- <persistence-unit name="Demo_Unit"> which provides us with the persistence unit name used by our EJB.
- <jta-data-source>MyDataSource</jta-data-source> As datasource definition.
<class>com.github.werpu.tomeedemo.orm.HelloEntity</class> For our enity class
The rest are internal openjpa settings, like foreign key handling, that we use compile time instrumentation instead of runtime instrumentation (see also the maven config for that one), or a helper which preserves the states in serialized scenarii, to help to speed up subsequent merges. Neither of that is if importance for the blog.
Now last but not least our entity class which is used by our service:
We use standard server hosted authentication for our application to limit user access to certain pages. Deeper knowledge on the mechanisms of this authentication method is outside of the scope of this blog, but you can find information here.
The application has a secured page which can be accessed from our landing page. For simplicty reasons we use the standard tomcat-users.xml file and the UserDatabase realm defined by tomcat as standard.
All we do is to add another user and a new permission to the realm:
The web.xml now has to have following entries to secure the page:
What we do here is to secure all pages under /user/* only accessible for users with the role authenticated-user which was defined before.
was the standard realm which we defined our new user and new role
We also define a login and error page for a standard login.
The login looks as follows:
This is a standard login form for server based authentication, it has to follow a certain naming syntax, hence, the non JSF syntax.
We could make it simpler by running our database in embedded mode, which would look like following:
This however has the downside of not being able to connect to the database with third party tools, while the db is running. While simplicty is the primary objective of the demo project, which this blog is based upon we stray away from this path in case of the DB. Our primary aim is to have a db which runs in server mode. Normally this would be an Oracle, MySQL or PostgresSQL db. However in our case we simply want the db to start once we start our own server.
For this we use a small trick, we use a servlet to start the db. (theoretically a context listener also would suffice)
The servlet has to be started via loadonstartup = 1
And the entry in the tomee.xml looks like following:
Almost the same as before however the JDBCURL parameter is different it now uses a TCP/IP connection instead of direct file access.
This sums up our little walkthrough through the demo application. Have in mind, that the application is a good kickstarter for your own projects, however in a real production environment some adjustments have to be made. For instance authentication needs to be set towards a database, passwords need to be replaced by their hash sums, authentication has to go through https, and also the db should not be generated out of the entities.
But all of this would sacrifice the simplicity of the demo project. Also feel free to comment or fork the project for your own purposes or improvements. Any participation is welcome as always in opensource projects.
- TomEE Maven project
- Apache TomEE project
- OpenJpa project
- Mark Strubergs blog (JPA and CDI information)
- Oracle server side authentication tutorial
- How to start HSQLDB in a webapp