Trust in Java EE

In these days there is so much noise about Microservices and scalable architectures. We read about Verticals, Multi Threading and Fat Jars. I ask myself what is all that good for? Didn’t we have an architecture which is still providing similar concepts –  called the Java Enterprise Edition?

What is the idea behind Java EE? The main job of a Java Enterprise Server is to server resources to your application. This means a Java EE application sever provides resources like Database connections and security realms. As a Java EE developer you have not to think about how this is done. You just lookup – or in newer days inject – a JNDI resource. This resource can be a database pool, a Mail Session, a LDAP connection or something else. The application sever is responsible about managing, pooling and scaling of these resources. Why not trust in that concept?

There may be some cases where big companies are running there business applications in an awful architecture. Sometimes you can see a productive environment with many tomcat instances, each running a single piece of code from the business domain. For example there are several war artefacts, one for the customer service, one for the order management and another tomcat is serving the offer management. And each module is running in a single servlet bringing its own JDBC connector and security with hard coded configuration. I think you can agree with me that this is nonsense and bad practice.

So why not trusting in Java EE? If you are using this architecture in the right way you can deploy all 3 war modules from the scenario above into one application server. Each war module lookup or injects the same JDNI database resource. The application server is responsible to manage JDBC connections. And the important part here is that these JDBC connections are running in several separate threads outside of your servlet. So why not using this facilitation?

The other part we should think about is the business logic. If you put all logic into one servlet the code grows up with the time. This can not be managed well and took a lot of resources on your web server (each time the servlet is called). Ah! That’s it – we need more verticals, microservices and servers to bind each part of our business logic into a separate thread. Looks so, but again we missed one of the core concepts of Java EE – EJBs. EJBs are by far the most misunderstood concept of Java EE. The reason my be historically, because EJBs where at the beginning awful complex. But today EJBs are perfectly easy. You can put as much as possible of your business logic into several stateless session EJBs and the application server is doing the rest. EJBs are pooled in a container. This means they are running in separate threads, are pooled by the server and are transactional. You can’t implement such a concept easily by yourself. And at least Java EE application servers can also be clustered.  So there is enough playground also to set-up large server environments –  if you like…

Conclusion

Java EE provides an architecture that solves the main problems of modern web applications. Although Java EE is several years old, there is not reason not to trust in this architecture. In my eyes it is no wasted time to seriously deal with this technology and consider all the ideas and concepts. Thus, Java EE at the end may be the best architecture to build the big brother of Microservices –  Self-Contained Systems.

Please let me know if you can give me arguments why I should rebuild my business application from a Java EE platform into a new architecture style like  Vert.x, Wildfly Swarm or something else?

JEE6 – How to package an EAR – Part II.

As I explained in my previous blog entry about JEE6 ear packaging, there is a flexible and powerful way to deploy EARs containing JEE component libraries.

Using maven makes it much easy to build such ear deployment units. The interessting part of the pom.xml of the ear module looks something like this:

 

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-ear-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <version>6</version>
                    <modules>
                        <webModule>
                            <groupId>myweb</groupId>
                            <artifactId>imixs-web</artifactId>
                            <contextRoot>/test</contextRoot>
                        </webModule>
                        <ejbModule>
                            <groupId>myejb</groupId>
                            <artifactId>imixs-ejb</artifactId>
                        </ejbModule>
                        <JarModule>
                            <groupId>org.imixs.workflow</groupId>
                            <artifactId>imixs-workflow-engine</artifactId>
                            <bundleDir>/</bundleDir>
                        </JarModule>                        
                    </modules>
                </configuration>
            </plugin>
        </plugins>
 ....

In this example the artefact ‘imixs-workflow-engine’ is a component library containingg EJBs. You can refere to those libraries from your ejb module (in this example ‘myejb’) by using the ‘manifestEntries’ tag in your maven ejb module configuration. This is what I explained here.

But what if you need some more additional external libraries containing non-jee-components (simple pojo’s like for example apache commons-xx.jars) ?

You can add those dependencies to your ear pom.xml – so these jars will also become part of the ear root directory. But now you need to add them again to the manifest file of your ejb module if you need access to these libraries. And this will result in a strange situation because indirect dependencies will make it impossible for you to manage your manifest file manually.

I run in this situation when a need the apache fop-1.0 library in one of my ejb components.

But the solution is again quite simple when using maven and the ear-plugin. The plugin provides a configuration tag named ‘defaultLibBundleDir’. And you simply need to the the value to ‘lib’ to get all your libraries moved in the default lib directory of an ear:

<plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-ear-plugin</artifactId>
       <version>2.6</version>
       <configuration>
            <version>6</version>
            <defaultLibBundleDir>lib</defaultLibBundleDir>
            <modules> 
         .....
  ....
</plugin>

But you need to be careful because also your jee-component libraries will be moved into that location if you did not overwrite the default behaviour now.  You can do this by declaring each of your jee component libraries as a ‘JarModule’ where you specifiy the ‘bundleDir’ with ‘/’:

....
<module>
 ....
  <JarModule>
       <groupId>org.imixs.workflow</groupId>
       <artifactId>imixs-workflow-core</artifactId>
       <bundleDir>/</bundleDir>
  </JarModule>
</module>
...

This will result in a ear structure where your own jee-components will become part of the root of your ear, and all other library dependencies will be moved to the /lib directory of your ear. So any libary can be seen from your ejb, web and component modules. And you jee-component.jars will still be parsed for JEE annotations during deployment.

I hope this helps you to build you own custom enterprise applications using all the strength of JEE.

 

Java EE6 – How to package an EAR

I spent the last weeks a lot of time to find out what’s the best way of packaging an EAR deployable on a JEE6 Application Server like Glassfish V3. I stumble on some problems when I try to deploy my EAR on Glassfish V3 which was running before on JEE5 Glassfish V2.1 server. Now I find out the missing parts and I want to describe my experiences here.

I am not talking about the typical EAR packaging situation you can see in the most of examples and tutorials where you have an EJB Module containing you business logic and a WEB Module containing your web frontend. As in JEE5 also in JEE6 it is pretty easy to deploy such an application. And there is in most cases no need to think about deployment descriptors as it was necessary before in J2EE (Java 1.3, 1.4).

What I tried to find out was the right packaging of an EAR including different libraries containing JEE components like EJBs, JPA Entities and Servlets on top of my EJB and WEB Module. I call such libraries “Component-Libraries” to indicate that these libraries containing JEE Components which can be used out of the box.

So first lets take a look on a simple situation where you want to package a simple JAR file together with a EJB and Web module. For example you have a JAR providing some POJOs used by both modules (EJB and web module). In this situation you can drop such a library simply into the /lib folder of you EAR. So your EAR should have the following structure:

[my-ear]
 - [lib]
     |- (pojo.jar)
 - [META-INF] 
     |- application.xml
     |- sun-application.xml
 - (my-ejb.jar)
 - (my-web.war)

As the pojo.jar is packaged into the /lib folder (which is the default location for shared libraries) both modules (the web and the ejb) can access the pojo.jar library. This is a typical situation and it is very easy to use.

But what if you have a component-library containing additional EJBs? If you package this library also into the /lib location like this:

[my-ear]
 - [lib]
     |- (pojo.jar)
     |- (ejb-components.jar)
 - [META-INF] 
     |- application.xml
     |- sun-application.xml
 - (my-ejb.jar)
 - (my-web.war)

the deployment will fail in most cases. The problem now is, that the EJBs  defined in the ejb-components.jar are in the top-level “lib” directory of the ear. That means the classes are visible to all modules in the ear. Each module (the my-ejb.jar and also the my-web.war) is processed for annotations, so the beans defined in the ejb-components.jar are created more than once. This is the reason that it is not recommended to put classes with component-defining annotations in a library .jar!

Ok – so lets put the ejb-components.jar out of the /lib folder location:

[my-ear]
 - [lib]
     |- (pojo.jar)
 - [META-INF] 
     |- application.xml
     |- sun-application.xml
 - (my-ejb.jar)
 - (my-web.war)
 - (ejb-components.jar)

But now the EJBs of the ejb-components.jar will not be deployed because this jar is not a declared as an ejb module. Ok – you can add the jar to the application.xml file and declare this jar to an additional ejb module like this:

<application xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd" version="5">
  <module>
    <web>
      <web-uri>my-web.war</web-uri>
      <context-root>/my-web</context-root>
    </web>
  </module>
  <module><ejb>my-ejb.jar</ejb></module>
  <module><ejb>ejb-components.jar</ejb></module>
</application>

This will work until you have to overwrite the ejb-jar.xml file. But this situation often occurs if you need to reconfigure the EJBs of the ejb-components.jar. And as you have no sources of this jar you can not easily rebuild it with additional descriptors. So now you have a real problem!

But there is a trick which enables you to take over control of all the EJBs defined in the ejb-componets.jar directly in your my-ejb.jar where you have the sources to build this module.
Simply add a Class-Path definition to the META-INF/MANIFEST.MF file of your ejb module:

Manifest-Version: 1.0
Class-Path: ejb-components.jar

Now the ejb-components.jar become a part of your my-ejb.jar and you can overwrite each setting in you ejb-jar.xml file. If you are using maven as your build tool you can add this additional Manifest entry simply by using the maven-ejb-plugin.

            .......
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-ejb-plugin</artifactId>
                <configuration>
                    <ejbVersion>3.0</ejbVersion>
                    <archive>
                        <manifestEntries>
                            <Class-Path>ejb-components.jar</Class-Path>
                        </manifestEntries>
                    </archive>
                </configuration>                
            </plugin> 
            .......

If you are not using maven simply add the MANFIFEST.MF file into your my-ejb module.

OK why did I talking about all this stuff? In the situation I describe here I assume that your are not in the role of the component-developer of the EJBs implemented in the ejb-components.jar. Your are in the Role of the component-deployer. In this role you do not change the implementation but you may want to overwrite some settings of the ejbs provided by the component-developer. For example you want to define a ‘run-as-principal’ role to a ejb or a method. Or you would like to rename a ejb or inject a local jndi-mail or jndi-directory resource by name. In this cases you can do this now by the ejb-jar.xml which is located in your ejb modle (my-ejb.jar) and which is under your control.

Remember – JEE is in first place a component architecture. This means you develop an ejb component once and you can reuse and run this component everywhere in your environment. I think this part of JEE is sometimes missed in lots of JEE projects. So this concept follows the goal to simplify your deployment and your project structure but also reuse complex components in an easy way.

SERVLETS AND JPA ENTITIES

Until now I explained how to deploy ejb component jars. Next I want to take a look on another kind of JEE components – Servlets and JPA Entities.

If you have a jee-component.jar containing Servlets you can follow the instructions above. A servlet provided by the ejb-components.jar will be visible to a web module as your my-ejb.jar is part of your EAR. But your servlet will not able to use injected EJB or JNDI Ressources. So an annotation with an EJB injection in your servlet code will not work:

public class WorkflowRestService extends javax.servlet.http.HttpServlet
		implements javax.servlet.Servlet {
.... 
    @EJB
    org.imixs.workflow.jee.ejb.EntityService entityService;
.....

The reason why the entityService EJB in this case will not be injected is that the servlet class located in the ejb-componets.jar is visible to the web module but the servlet will not be scanned for injections because it is now part of our EJB module. So it is not recommended to deploy a component-library containing a servlet in the way described before.

Component-libraries containing Servlets and also JPA Entities can be still placed into the /lib location of your EAR.

[my-ear]
 - [lib]
     |- (pojo.jar)
     |- (servlet-components.jar)
     |- (jpa-components.jar)
 - [META-INF] 
     |- application.xml
     |- sun-application.xml
 - (my-ejb.jar)
 - (my-web.war)
 - (ejb-components.jar)

In this case your servlet from the servlet-components.jar is visible now to the web module (my-web.war) and Injection will work as expected. So do not! mix up EJB, JPA and WEB components into one component-library. This is also important as you increase the deployment flexibility of your project for future.

I the case of the jpa-components.jar there is another detail to be pointed out.

I assume that the jpa-comonents.jar includes Entitie EJBs like this:

package org.imixs.workflow.jee.jpa;
.....
 @javax.persistence.Entity
public class Entity implements java.io.Serializable {
......

The Entities are typical injected by EJB components using an JPA EntityManager

    @PersistenceContext(unitName = "org.imixs.workflow.jee.jpa")
    private EntityManager manager;

As the jpa-components.jar is now located in the /lib folder of the ear you need to declare the location of the jpa unit in the persistence.xml file. And now I am back to the my-ejb.jar module where you are the component-developer. As you control this module you can place the persistence.xml file into the META-INF folder and define the location of your jpa-component.jar there:

persistence.xml:

<persistence>
    <persistence-unit name="org.imixs.workflow.jee.jpa">
        <jta-data-source>jdbc/workflow-db</jta-data-source>
        <properties>
            <property name="toplink.ddl-generation"
                value="create-tables" />
        </properties>
        <jar-file>lib/jpa-components.jar</jar-file>
    </persistence-unit>
</persistence>

So again you have full control about the deployment of all your components provided by third party component-libraries.

CONCLUSION

After some problems starting deploying my EAR on Glassfish V3 (migrating from Glassfish V2.1) I think JEE6 is still a flexible and powerful application platform. Also the platform supports strong capabilities in the configuration of complex applications and the usage of third party components. And JEE6 is a component architecture which supports a modular concept of build applications from components to be reused in different situations.

But I still have some problems in deploying WebService components from a component-library. I will continue to figure out how to deploy such components. If you have any suggestions or comments please let me know and post them here.