Let’s move to Java EE 6 – or not?
September 14 2011 by Daniel Meyer · 1 Comment
Lately, we have many clients asking us whether they should make the move to Java Enterprise 6. I think that the answer depends on where you are coming from and where you want to go with your project. No really?? You don’t say…
No seriously, while the Java EE 6 programing model offers superior functionality / key stroke and a new generation of breath-taking-cool application servers is out, it might not be a good fit for every one. At camunda we think that Java EE 6 is very well suited for implementing process solutions. At the moment we are pursuing two themes: we offer a Java EE 6 training where we cover both general topics and specific technical business process implementation patterns and on the other hand, we are currently developing advanced activiti integration for the Java EE platform. In this post I want to summarize my current position on Java EE 6 and the question on whether one should migrate to the new platform.
What is Java EE 6 about?
Let’s start by getting a few facts straight: Java EE 6 is the coolest thing since sliced bread. If you have any dusted (or maybe very life) memories about that technology they called J2EE, forget it, it has nothing to do with that. If you have used the Spring Framework or Jboss Seam 2, you are getting closer. Java EE 6 is a complete, standardized platform for getting things done; it lets us focus on business requirements, without having to worry about different technologies and libraries and how to configure them so that they work together. Ok, so admittedly I like Java EE 6
I bring you beans, you make me coffee: The Java EE 6 Programing Model
EE6 is about beans (plain old java objects) and offering them the services they need to realize their business functions. So I can start with a simple java class and put my logic there:
public class SeminarService {
EntityManager entityManager;
public Seminar createNewSeminar(String name) {
Seminar seminar = new Seminar();
seminar.setName(name);
entityManager.persist(seminar);
return seminar;
}
public Seminar getSeminarById(String id) {
return entityManager.find(Seminar.class, Long.valueOf(id));
}
}
Ok, that was easy. This is exactly what we want to write – plain business logic. But wait, that can’t work, can it? – Well, almost. For this code to run successfully, we have to add two annotations. In order to use the services provided by the container, we have to tell the container what we need. Think about that entity manager: we certainly do not want to manage it ourselves, so we just tell the container to inject it:
@PersistenceContext private EntityManager entityManager;
And that is all. This gives us a transaction scoped entity manager which means that we need transactions. Transactions are also just a simple annotation away:
@Stateless public class SeminarService
And done! The container will now make sure that a transaction is active for our methods. But wait, you are asking: that does make it an EJB, doesn’t it? And again, you are right: a big fat EJB!
Only that they are not that fat anymore. With EJB 3.1, we have no-interface views and we can access EJBs from the web tier using expression language by just adding another annotation:
@Stateless @Named public class SeminarService
And now we can write #{seminarService.getSeminarById(id)} in our JSF pages. We can also inject it in other beans using the @Inject annotation.
This very basic example should illustrate the general programing model in Java EE6: I provide the beans and declare which container-provided services I need, the container provides the services. Just to make it very clear, how “far” this goes, let’s add a different container-service:
So you are still not entirely happy with the EJB: now it is @Named, but you do not want to use JSF, you want to write a cool jQuery application and use a Java EE as backend. Gladly! Let’s get JAX-RS booted:
@ApplicationPath("/rest")
public class JaxRsActivator extends Application {
}
And expose the getSeminarById(String) method using REST:
@Path("/seminar")
@Stateless
public class SeminarService {
(…)
@GET
@Path("/{id:[0-9][0-9]*}")
@Produces("application/json")
@TransactionAttribute(TransactionAttributeType.SUPPORTS)
public Seminar getSeminarById(@PathParam("id") String id) {
return entityManager.find(Seminar.class, Long.valueOf(id));
}
}
And again: that is all! We could just as easily have used JAX-WS and exposed the service as a webservice.
To step on that point again: the Java EE 6 application server provides a set of commonly used services to applications and I choose what I need. I do not have to configure a JAX-RS provider or a JPA provider or a transaction manager, it’s just all (Security, Transactions, Resource management, Webservices, Rest, JPA, Events, Interceptors, Dependency Injection, Messaging, … ) there and I take what I need.
I need more than Coffee: Extending Java EE 6 with CDI
But wait: what if that is not true? What if I need a service which is not provided by the platform – Say I want to use declarative transaction management in plain CDI beans (without EJB): no problem, let’s just do it!
I start by declaring an InterceptorBinding:
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@InterceptorBinding
public @interface Transactional {
}
This is the annotation I add to my methods when I want to make sure that a transaction is active when they are called. Now let’s add a simple interceptor that starts a UserTransaction when such methods are called (if no transaction is already active):
@Interceptor
@Transactional
public class TransactionInterceptor implements Serializable {
private static final long serialVersionUID = 1L;
@Inject UserTransaction userTransaction;
@AroundInvoke
public Object invoke(InvocationContext ctx) throws Throwable {
boolean startNew = userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION;
if (startNew) {
userTransaction.begin();
}
try {
Object result = ctx.proceed();
if (startNew) {
userTransaction.commit();
}
return result;
} catch (Exception e) {
if (startNew) {
userTransaction.rollback();
}
throw e;
}
}
(Exception handling stripped for brevity.) The cool thing here: I can now just write my own interceptors, without having to worry about bytecode enhancement and all that jazz, against a standardized API. So while something like this was a “hack” inn EE 5, it is not in EE 6.
Making the coffee myself: Using Java EE outside of the application server.
What if I do not want to use a Java EE 6 application server? Short story: it works but it is painful. When thinking about Java EE 6, I see two things: the platform and the programing model. If I want the programing model without having the platform available, I have to assemble (parts of the) platform myself. So basically I have to build my own application server. The problem is that if I take away the app server, I take away the “glue” that holds it all together and I find myself standing there with all these individual components and frameworks in my hands (persistence, messaging, transaction management, UI frameworks …), not sure how to integrate them correctly. Now I do not simply have to add that @PersistenceContext – annotation and provide a persistence.xml file to use JPA, but I need to reference hibernate from my maven pom, I have to configure and bootstrap the persistence unit aka “session factory” and find a way for the application to build entity managers aka “sessions” and use them. This is difficult for two reasons: first I have to get it right technically and second my developers have to learn how my particular custom entity manager propagation scheme works (“when are sessions opened and closed?”) – In EJB 3 it’s clear: one entity manager per transaction or an extended entity manager with custom lifecycle management – end of story. Good developers know this and use it correctly. The same is true for resteasy (Rest), weld (cdi), acive mq (messaging), atomikos (JTA), spring security (security), tomcat (servlet), mojarra (jsf), jndi (spring framework), dependency injection (spring framework), platform abstractions (spring framework) … . Now I have to know the names of all these implementations (before I just had to know the api), I need to find out which versions work together (and which versions do not) and how to integrate all this. Now basically, I am building my own application server. Because, and that is the problem: I still need these services! So the bottom line is that the application server is an integral part of the Java EE 6 platform. Taking away the the app server is taking away some of the arguments for using EE 6. “So now the application server is a good thing!?!? For the last 8 or so years people have been telling me that it is bad.” you ask. Yes: an extremely good thing! (More on this below.)
So to summarize this: Java EE 6 is about 3 things:
- The programing model which is powerful yet lightweight and extensible,
- The technical platform (application server) which offers me the services I need – and does so out of the box,
- A third reason I forgot but which was along the lines of EE6 being totally awesome and cool.
How is Java EE 6 different from previous versions?
In a large number of ways: we have to write less boilerplate code; there are new services like JAX-RS, or CDI, new declarative, contextual programing model and many others, but let’s forget about all of this for a moment. I think there are two very key differences:
Extended Target Audience: EE 6 Web Profile
EE5 was a giant leap forward and towards what developers and architects really need: a powerful yet flexible programing model. EE 5 introduced the JPA persistence framework and JTA transaction scoped entity managers in EJB. In addition, the extended persistence context was introduced, which allows to scope entity lifecycle to a longer lasing unit of work. These were milestones (among many others). However, EE5 was still very “enterprisey” i.e. well suited for large enterprise projects, with advanced technical requirements but less well suited for smaller web-centric projects. EE 6 features the web profile to fill that gap. The web profile brings a lightweight component model and restricted set of components to the web developer. This allows us to start small(er) but grow big, if advanced requirements like asynchronous EJB-timers or advanced messaging surface at later project stages.
So EE 6 is not only targeted at large-scale enterprise software projects but also at small(er)-scale web applications.
Dramatically better Application Servers
Traditionally app servers have been heavy weight and promoted vendor lock-in. Looking back, I think they had two key problems:
- boot time was way too slow and memory consumption was disproportionate – this was the case because traditional app servers basically started all the services an application could possibly need (so even if no application needed messaging, the JMS queues were stated) and loaded all classes they could find, one class at a time.
- they did not shield us enough from their own classpath. So let’s say I am on Jboss AS 5.1 and I need to use a newer version of javassist than the one that ships with the app server. What do I do? – Replace the jar in the server’s main lib directory and then run to the pharmacist’s for sleeping pills because that’s the day I definitely sacrificed my peace of mind.
The reaction to this was that people moved away from the app server to lightweight containers like tomcat or jetty which just implement the servlet specification and shipped everything else themselves.
But that game has changed. Big time! EE6 app servers provide that sweet out-of-the-box-integration of the components I need but fix problems 1 & 2 named above. For example, on Jboss application server 7, if my deployment does not use JMS or JPA, it will not start these services. But they are still there, waiting for me to add that one annotation. If I use Spring, I have to crawl the web for that magic 20 lines of xml code that solve all my problems. Plus, modern application servers are highly optimized. We saw that modern applications make extensive use of annotations. During deployment, Jboss AS 7 will scan the classpath once and build a global annotation index (jandex) that is then reused by all components. And, of course it only loads the classes I need and does so concurrently. So you cannot possibly be faster than a highly optimized application server. In addition, due to modular class loading, I can control on a fine grained scale which libraries are included in my classpath and I can deploy multiple versions of the same library at the same time.
So nowadays, the application server is actually an asset, not some ball and chain which ties me down.
Ok, enough already – so we should all use EE6, then?
Hey why interrupt me? I could go on… but then again you already seem convinced. Well ok then, let’s revisit the initial question. This is the deal:
- Existing J2EE applications: you waited that long and the application is probably working quite well by now: no lightheaded experiments! If you face complex new requirements, start with the web tier and migrate to CDI / JSF 2. This allows experiencing productivity gains where new requirements are most common and often the most complex. This also allows the team to make first contact with the dramatically different programing model and the blazingly fast application servers (which are your primary argument for selling your move to the developers). Make sure the developers have a solid understanding of the JSF2 lifecycle, templating, typesafe CDI injection rules and contextual state management. Once the team is familiar with the new technology and programing model, you can think about the transactional tier: here large scale refactoring is necessary. Make sure the team exactly understands the interplay between transactions and entity manager propagation. Once you have overcome the initial problems, you will notice that you actually have a lot less code! And the code you have is easier to understand, refactor and maintain. One last recommendation: try to exploit the new flexibility, do now try to reuse old J2EE patters just because this is what you always did – it is a new programing model, embrace it, it will pay off!
- Existing EE 5 applications: if you practiced the “pure art” of EE 5, (ie. without an additional framework like Seam 2), you can probably move to EE 6 quite easily, from a technical perspective. However, in order to experience the true power of EE 6, you have to get familiar with the new declarative contextual programing model. Here I have no real migration path available. I think the best is to do a radical cut at a point where project management allows it or if you have to integrate a couple of new developers to the team anyhow. And then look at CDI very closely and try to really understand it (ie. contextual lifecycle management and typesafe injection). You will notice that you can eliminate purely technically motivated architectural layers like session facades or entity access in most cases. So you will also end up with less code and higher productivity.
I think some Seam 2 users should actually wait a little bit before making the move. I think it depends on how much Seam 2 provided integration features you use: if you use the Seam 2 mechanisms for sending emails, rendering pdf, pageflows etc. and you are happy with it, then you can actually wait a little bit before moving to EE 6 until Seam 3 provides the same rich set of features and is as mature as Seam 2. You are probably already highly productive and conceptually you are already familiar with the new programing model of contextual state management, so there is no hurry. Your motivation for moving to EE6 is being able to use the new app server (which is also a risk/investment at first) and moving away from a proprietary platform to a standardized, portable one. You will also miss some advanced Seam features like nested conversations in EE 6. - Existing, non EE Applications, Spring Applications and new Projects: I think there are different “kinds” of projects, some of which are a good fit for Java EE and some of which are not.
Some are “larger than Java EE”, i.e. if you are conducting an enterprise-wide SOA project, Java EE is not “enough”, neither in terms of infrastructure nor in terms of the programing model. However it is a good programing model for implementing (some of) the services and user interfaces. In this context EE 6 contributes an overall “lightweightness” in contrast to previous versions and a standardized approach to RESTful Web services (JAX-RS).
Software vendors: as we said Java EE 6 is difficult to use without an application server. If you are developing applications that target servlet containers like tomcat and jetty: think about using the spring framework. It is very mature and robust and offers platform abstractions that allow you to deploy the application in a maximum number of environments. The trade-off is that if you cannot reuse an application server, you have to setup services like persistence, transactions and messaging yourself. IMO this is the key use case for the spring framework.
If you are building dedicated business applications, move to Java EE 6 and get yourself a modern app server like Glassfish 3.x or Jboss AS 7. You will be more productive and have the possibility to focus on business requirements and worry less about technology. It is all there!
And if this is still not enough, I am going to give you the killer reason: EE 6 has first class activiti integration! But more on this later…



[...] A couple of days ago, I promised that I would unveil “first class activiti support in Java EE 6”. Today I will give you a first taste. But keep in mind: what I am showing below is cool, but: it is by far not the coolest thing we have currently lined up. So stay tuned. [...]
2011-09-18 um 9.06 am Uhr. Verfasst von BPM-Guide.de It’s Business Process Management » Build your own activiti task explorer with CDI and JSF 2