Why does JEE fail?

11 reasons why you should reconsider using JEE.

JEE is slow

Startup and deployment time of JEE is slow. If you want to prove it, use the following search algorithm:

for v in versions:
        search(serverName, version, "improved performance")

Every release of JBoss or Glassfish or whatever JEE server, tells you that performance is now great.

Well, it is wrong. It is still not great. The startup time of an empty server is reasonable. Deploying an application larger than “Hello World” is slow.

That consumes a lot of development time.

JEE is unproductive

Writing code using EJB 3 is way more efficient than EJB 2. This is really true. So, we finally reached the speed of a turtle. Deployment turn around times, complex unexpected behaviour, hard to find reasons for exceptions or complex features enabled by default drain your productivity.

In many cases JEE is totally inadequate for enterprise application, apart from the well chosen name. Many enterprise application are very primitive. As Paolo Perrotta put it once: Most enterprise applications are simple. They take the data from somewhere, massage the data and send the data somewhere else. How hard is it to come up with a development language which can’t solve such a problem well? Well, JEE doesn’t.

JEE is not for parallel processing

Of course, you can process multiple requests or messages in parallel. Every request is processed on a single core. Let’s look at a use case.

There are the following processing steps: a, b1, b2, b3, c, d1, d2

You can parallelise b1, b2, b3 and d1 and d2. It is discouraged in JEE to start your own threads and doing it correctly for example on JBoss just requires a few lines of code. ;-)


To rephrase the title, JEE is not made for fine grained parallel processing.

Normal parallel processing can be complex as JEE server uses a model which made much more sense 15 years ago. It creates a pool of instances for every Session Bean. For a request an instance is taken from a pool and returned to the pool afterwards. If you misconfigure the pool, the whole thing blows up or even worse times out.

JEE is slow (again)

JEE is scalable. This is nice but not a unique selling purpose in 2013. Hey, you can scale anything today.

JEE is a proxy nightmare with many things happening behind the scenes. A proxy around a proxy around a proxy connected to a transaction and resource manager.

Are you aware of a really big system which uses JEE? I am talking about really big.

JEE requires a 27" screen in portrait format

If an exception happens, you see a nested exception with a stacktrace of a nested exception with a stackstrace of a …

If you are used to Ruby web frameworks or the Tapestry framework, which points you to

then using JEE feel like being a monkey who just climbed down from the trees and scrolls and scrolls and scrolls and scrolls.

How much time of your life do you want to waste on scrolling stacktraces?

JEE fiddles with exceptions

Given a runtime exception from a Session bean which started a transaction, would you expect a rollback? Yes, I do and it works.

Given a runtime exception from a Session bean which was called from a Session bean which started the transaction… EJB, would you mind not fiddling with my transaction? It is my exception, stay away from it. It might be recoverable.

Even worse, not only does JEE destroy my transaction and forces me to sprinkle catch blocks for Runtime exceptions all over the place, it wraps it with an EJB exception.

So, I have to inspect the cause of the transaction and possibly the cause of that transaction to find out what happened.

JEE is procedural

Do you like “Head First Design Pattern”, “Refactoring: Improving the Design of Existing Code” or “Refactoring to Design Pattern”?

Forget it. JEE is procedural. Did you ever try to apply a template pattern or a factory method? It is somehow possible, but do not expect very nice code.

The more I use JEE in big projects, the more it feels like Cobol. Not because it is outdated, but because it is more procedural than OO.

EJB means call a Session bean, which calls another session bean, which might call another session bean.

In fact it is procedures with class namespaces.

EJB leads to ugly code

Since EJB 3, we no longer have to inherit from specific classes, but still:

It is a basically an invitation to write non-object oriented code, and so do the application look like.

JEE is hard to test

Many developers write unit tests. Do you write acceptance tests as well, to verify that your classes play well together? “Growing Object-Oriented Software” is a great book, teaching to write tests for different abstraction levels. Unit test on a single class do not find all the problems. The system – multiple classes playing together – needs to be tested as well.

Testing with JEE is not trivial and really difficult when you start with acceptance testing. You have to mock objects and JEE behaviour. It requires careful design and interaction with resources to have testable code.

Why not use Arquillian? It allows to start an embedded JEE server and deploy only a fragment of your application and test it in a mostly real JEE environment. It is out of question that the Arquillian people made a great work. The framework can help in many situations.

But on the other hand, Arquillian solves problem you would not even have if you stayed away from JEE.

JEE is like a 300 year old castle

It is like an old castle where every generation added a new wing or tower. Innovation does not take place in the internals but it is added as parallel functionality because backwards compatibility is a must.

There is now EJB and CDI injection. So there are two sets of annotations sometimes with the same names. Session Beans and CDI classes can or cannot work with each other, depending on how you plug them together. Can you explain which CDI context plays with which JEE contexts and when CDI will instantiate a class or not, or delegate, or…?

JEE makes it difficult to parallelise work

It is the year 2012, we talk about the end Moore’s law and are having languages like Erlang, Clojure to allow parallel processing. It is normal to start threads, having exchange barriers and other cool stuff. The JVM has considerable improved in this area. JEE is totally inadequate when you want to process small grained pieces in parallel. Asynchronous methods are not enough. The basic EJB concepts have been more or less unchanged for more than 10 years.


This statement is focussing on JEE weaknesses. Other people might come up with there 11 reasons to reconsider using JEE. Probably there are use cases where JEE is useful. But in my opinion those cases are limited. For example, message processing, Web or REST services do not require JEE.

Using light weight technologies avoids a lot of complexity in development.