Still Too Many EJBs

10 PM July 15, 2003

A couple of days ago, Hani wrote an entry about on the topic of my Too Many EJBs post. Hani had a couple of good points and a few really bad ones.1 The good points were that I need to ‘join the dots’ in the argument between the list of pros and cons and the article’s conclusion, that I should quantify the meaning behind “a LOT” and that I should explain what “eat memory and CPU cycles for no discernable benefit” means.

I’ve worked on two large J2EE systems. The current one has more than a million lines of source—1.5 million with generated code—and 500 EJBs distributed over twenty or so subsystems. Both this system and the one I worked on previously were designed similarly:

  • Servlets make calls to Stateless Session EJBs designated as “Use Case Controllers”.
  • The Use Case Controllers call a second tier of Stateless Session EJBs.
  • The second tier manipulate data through CMP Entity EJBs or another layer of Stateless Session beans that access files or external systems.2

I know of several other large J2EE systems designed similarly, and none that are very different. But your mileage may vary.

Joining The Dots

Here I explain how I moved from the list of pros and cons to the conclusion that only one EJB per subsystem is required. The ‘first EJB’ is the Use Case Controller EJB that provides access to the subsystem. The “more EJBs” are the ones behind that that actually do the work.

The first part of this argument was that all the advantages of using EJBs are gained with this first EJB:

Pro First EJB More EJBs
Individual EJB-wrapped components can be distributed Defines the component, letting you distribute it. Add no advantages for distribution.
Resource pooling Provides you with hooks into the EJB container’s pooling. Provide you with more hooks, but you only need the one.
Container managed transaction scope Notifies container when you activate the component, so that it can start a transaction Also notify the container, but it doesn’t matter, because EJB transactions can’t be nested.3

If you know of additional benefits, please leave a comment.

The second part of the argument was that the disadvantages accrue with each and every EJB:

Con First EJB More EJBs
More effort to implement Write the bean interface, the home interface, the bean functionality, configure in ejb-jar.xml Do it as many times as you have beans.
More effort to use Requires use of PortableRemoteObject. Must be careful about letting run-time exceptions slip past the EJB (because they cause a rollback, whether you wanted it or not). Must manipulate through an interface that is not implemented by the code you are calling. Multiply by number of beans you have.
Calls take longer Even if in-container, each call incurs small overhead managing the state of EJB and serialising parameters. The more EJBs you have, the more likely you will want to interact with one in a tight loop.
Must use JNDI Use JNDI to get the Home interface, which you need unless you can get a bean reference from elsewhere. More beans means more interactions, means more JNDI.
CMP Entity EJBs With just one EJB, you probably don’t have any. They take more effort to implement, than a roll-your-own persistence layer, let alone a purpose-built Object-Relational mapper.
BMP Entity EJBs Ditto Combine the worst aspects of roll-your-own and Entity EJBs
Stateful Session Beans Session Bean more appropriate as the only EJB in a component. The canonical example of a stateful session bean is the shopping cart, but there are better ways to build a shopping cart.
Configuring Containers If you use EJBs at all, you incur a container configuration cost Additional cost incurred to ensure each EJB has the right JNDI name, transaction attributes, access intent, and any “user” configuration required
Container Eats Memory Container typically requires megabytes of Java code, plus many more megabytes for EJB cache, lookup tables and other internal structures Each EJB brings more generated code, plus additional requirements for the internal memory structures

What “a LOT” Means

I was surprised that anybody who has used EJBs would want this spelled out, but here goes:

  • An EJB takes a LOT more effort to implement than a standard Java object. The “LOT” refers to the two additional interfaces, multiple configuration file entries. and plethora of rules as to what you may or may not do in an EJB or a class called by an EJB.
  • Any EJB takes a LOT more effort to use than a standard Java object. Mostly means that I despise PortableRemoteObject. I have written about this before, though Charles does a more thorough job than I. It also refers to the jumping through hoops to get an object reference, remembering that the parameters may (or may not) be serialized, being careful with runtime exceptions and taking any transactional or access-intent set in the configuration files into consideration.
  • Any call to an EJB takes a LOT longer than a call to a standard Java object. On my EJB container of choice, EJBs have between four and six generated support classes. At runtime, a method invocation on an EJB will traverse at least two of these classes. These support classes make calls to the container support libraries to, at a minimum, activate and deactivate the EJB. The container I use serialises and deserialises each and every parameter, regardless of whether the target EJB is in the same container or not. Compared to making a simple Java method invocation on a real Java object, an EJB method invocation takes a long time.

Eating Memory and CPU Cycles for No Discenerable Benefit

The commercial EJB containers I have used take thirty or forty seconds to come up with only a single EJB deployed. Some of this is initialising Servlet and EJB containers and bringing up essential services like JNDI. The more EJBs deployed, the longer it takes. The application I’m working on takes at least five minutes before it’s good to go.4 At this point, it has consumed 600,000,000,000 CPU cycles and 150,000k of memory, and it still hasn’t done anything useful. Running in development, memory usage levels out at about 250Mb, not much of which can be paged out because of the JVM‘s garbage collection.

Of course, this is a big app, and it requires considerable resources. But with fewer EJBs, it would need less resources to do the same job, reducing start-up time, memory usage and response time.

Final Thoughts

These arguments don’t consider any of the soft issues that surround the construction of a large J2EE system. There are often good non-technical reasons for choosing to use EJBs, and even to use many EJBs. Also, I’m not arguing that existing systems built with “too many EJBs” don’t work or should be rewritten.

What I am advocating is this: if you are building a large J2EE system, think carefully before scattering EJBs willy-nilly through the design.


1 I can’t resist replying to two. First, my original post never advocated one EJB for an entire system. Hani might have understood this, but his writing was unclear enough that at least one of his readers didn’t.

And “l33t php app”? Is that the kind of reasoned, intelligent argument Hani is looking for?

2 Even though accessing system resources in this manner is against the EJB rules.

3 See section 11.1.2 of the EJB 1.1 spec. It is possible to suspend one transaction and start a second one, but this is not typically needed in a commercial application.

4 Ten or twelve in debug mode, longer if the shared database is heavily loaded.

By alang | # | Comments (13)
(Posted to Software Development)

Comments

At 00:29, 16 Jul 2003 Matt Comer wrote:

Odd. I also worked on a project that used "Use Case Controllers" as the session facade. I objected all the time, to no avail.

Mapping software objects to use cases in this way leads to redundency and lack of reuse. It does not take into account the proper model for the problem domain. It focuses completely on the user's interactions with the system and their workflow rather than on the domain level objects and their interactions.

Sound like your system may have been somewhat more complex than this with a second tier of objects that represented the problem domain. We didn't.

(#)
At 00:43, 16 Jul 2003 William Jones wrote:

I agreed with your first post and with this one also. I have been considering for a number of years (about 3 now) writing a book entitled "Not Everything Is An EJB".


A system we have recently finished was required to be distributed so that it could be split into 3 tiers (or tears) - web, application and database. We went for a single EJB stateless session bean model using a command pattern framework to pass to commands down from the web-tier to the application-tier. We used the OfBiz Entity Engine for persistence. We got what we wanted from EJBs - transactionality and separability - but only had to endure the uglification of one package (the dispatcher). The result - faster performance, faster development, shorter deployment cycles, increased portability.


Some of the replies to your previous post made allusions to having to duplicate remoting, persistence and security code if you don't use EJB. This is the sort of thing you'd expect to hear from an Oracle or IBM consultant (or similar) who are used to selling to Dibert-esque managers and who have a vested interest in obfusation and tie in. Anyone who thinks that EJB security maps onto their application's security requirements is clearly a few bytecodes short of the full method.


I could go on.... but it's your blog not mine! You do speak sense here though.

(#)
At 01:33, 16 Jul 2003 Bob Lee wrote:

> I have been considering for a number of years
> (about 3 now) writing a book entitled
> "Not Everything Is An EJB".

Have you checked out _Bitter EJB_? ;)

(#)
At 02:22, 16 Jul 2003 William Jones wrote:

> > I have been considering for a number of years
> > (about 3 now) writing a book entitled
> > "Not Everything Is An EJB".
> Have you checked out _Bitter EJB_? ;)


OK... so I missed the boat on that one... although mine would be better described as _Batter EJBs_ ;-)

(#)
At 03:58, 16 Jul 2003 Dave wrote:

The whole idea of EJBs calling EJBs is to achieve re-use. The session facade basically exposes methods for each "thing" the user wants to do, in other words, gives the client the easiest possible interface while abstracting the business logic down to one method call.

Behind the scenes, many use-cases rely on the same business logic, and so the second tier of (in the example) EJBs provides access to that logic. So, your session facade EJBs do the actual re-use of business logic as needed.

Now, should those be EJBs? Yes and No. Why not use local interfaces? Shouldn't that alleviate the performance issues? Still, session beans are a monumental pain to implement and deploy compared to regular Java objects.

As to the "one bean...many beans", that is a serious source of confusion. You shoudl be more specific with your language. To me "First EJB" means that very first EJB, and more means, well, more. THat's not what you actually mean. In your system, all the session facade ejbs are "first EJB"s. That makes no sense. First implies that only one can be first. Instead refer to them as "Facade" or "Client-Facing" EJBs and the others as "Server-side only" EJBs. Or something descriptive.

(#)
At 04:17, 16 Jul 2003 wrote:

Why should you use EJBs once you describe more EJB's Cons than Pros ? So, Let's use common objetcs.

(#)
At 04:34, 16 Jul 2003 Dave wrote:

I don't understand your sentence. Once you have yoru session facade EJBs, you may not want to use EJBs internally to achieve re-use. Or you may. If you choose to, local interfaces should be used (and I think it's retarded that you have create local interfaces; the appserver should do it for you).

Using EJBs, however, gives you the ability to just redeploy the EJBs in question when you have to change business logic or fix code. Using POJOs usually requires a server restart, since few app servers support hot-deployment of regular java classes (AFAIK).

(#)
At 09:20, 16 Jul 2003 James wrote:

Whilst some of the comments are article are valid,
there is more to using EJB than just how long they take to write (use XDoclet), and how many machine cycles they chew up (use performance analysis). What about management ? What about distribution ?
All the article point are valid if you have a really narrow scope / focus.
Just because the project you worked on had too many EJB's it doesnt mean that the world should only use 1 per component or they will be doomed.
The article takes a very black and white view, then suggests throwing the baby out with the bath water.

(#)
At 11:46, 16 Jul 2003 Jed Wesley-Smith wrote:

just a reminder that all params get serialized due to pass by value semantics, and there is no Immutable interface to indicate situations where this is unnecessary.

(#)
At 12:27, 16 Jul 2003 Alan Green wrote:

Parameters often are serialized, but there is no requirement for them to be. The generated support code for the container that I use seems to cope with both options.

In the end, you should write code that works with parameters that are passed by either value or reference.

(#)
At 07:51, 17 Jul 2003 choudary wrote:

Come on...this does not need so much analysis. The simple fact is EJBs other than Stateless Session Beans are pretty useless. Just give me a single 'real' advantage of Entity Beans.

But let's be honest and realistic...we need them to waste more effort, to waste more money, so that more money can be spent. It's good for the economy. Sun has the larger good of the world in mind when they painstakingly fixed the problems of entity beans in EJB 2.0.

(#)
At 05:31, 17 Sep 2003 Non Jerky wrote:

POJO, servlets, and web services baby! No more nerdy E.J.B. (Excessively Jerky Bullshit)! In the vast majority of cases using EJBs is analogous to building a nuclear bomb to kill a rat.

(#)
At 04:42, 07 Apr 2004 Richard Mottershead wrote:

Another PRO for you:

Reducing the Remote-EJB head count dramatically reduces deployment administration work especially for Group/User to EJB Security assignment.

Fine grained security on a function by function basis has to be done in the EJB by a local Authentication component.

(#)

Add Comment




(Not displayed)






(Leave blank line between paragraphs. URLs converted to links. HTML stripped. Indented source code will be formatted with <pre> tags.)




© 2003-2006 Alan Green