Thursday, March 10, 2005

EJB's: reasons to avoid

http://discuss.joelonsoftware.com/default.asp?joel.3.91272.13
There is a growing sentiment in book and non-book form that EJBs don't provide enough benefits for their considerable costs. Witness projects like the Spring framework and books like Rod Johnson's 'J2EE Without EJB' and Bruce Tate's 'Better, Faster, Lighter Java'. The only place where the benefits seem to outweigh the costs is with distributed transactions.

Some of the mythical benefits of EJBs:
1) 'You get declarative transaction handling'. This can be an OK benefit if your transaction needs are simple and straightforward (for example a single method is always a single transaction). If you want to start stringing together multiple methods into transactions (I can't imagine why anyone would need to do that) you have to start using certain design patterns to get around the limitation. At that point you may as well just do the transaction handling yourself because its not really that hard and you'll never have to spend the day trying to figure out what is wrong with your deloyment descriptors.
2) 'You get scalability'. People referring to this are usually referring to object pooling and the perceived notion that J2EE includes clustering support. The J2EE spec only makes mention of clustering support as a vendor specific add on. Most of them support it and they do it to varying degrees with varying levels of effectiveness. There is nothing in EJB that makes clustering easier - in fact it usually makes it much harder (what happened to my bean? why is it on server A when I want it on server B?) In regards to object pooling the only bean type that supports pooling are stateless session beans. Since the beans are stateless I can't really figure out what you get by having more than one of them. A simple singleton is an excellent replacement with none of the pool management overhead (I seem to have a reference to a non-existent bean. I guess I'll just write a whole bunch of call re-try logic - every time I make a bean call anywhere).
3) 'You get object persistence for free! FREE!!!' Entity Beans are just an all around bad idea. And a well documented bad idea too. See Bruce Tate's 'Bitter EJB' - he has a few chapters dedicated to why it's a bad idea.
4) Security. The only thing that EJB security really does for you is allow you to declare which application roles have execution permissions on which methods. Sounds nice in principle but in my experience it doesn't justify both the runtime costs and the configuration effort (get ready to trudge through a slew of XML files every time that you add/modify/remove a method). There just aren't enough methods where you are really adding security by saying 'These kinds of users can't execute this method'. Real authorization is often more complex than that and usually involves the data itself (user A can modify account number 123 but not account number 789).Don't neglect the costs of EJB usage either. There's a reson why EJB generates all of those classes for you. They're going to get executed. Every time you make a method call. You'll also pay some of the prices of remoteness even when most deployments don't involve remote communication. Sure you can use local interfaces if you know ahead of time that the call will be local - but there is still some overhead like JNDI lookups and whatnot. Why do a JNDI lookup when a method call will do?
The development costs are considerable as well. Configuration files can be an absolute nightmare - although there are tools to mitigate some of the issues. You'll start to wonder exactly what the point is when you're apending more time digging through XML than code. Server/application load times can be horrendous if you have more than a few beans. Not so bad for production but it's a real drag for development to wait 3 minutes for a server restart every time you want to test your code. But hey it's not like you do that 50 times a day or anything ;) And everytime all of the developers are sitting in a room trying to figure out just how it is that these classloaders are working. Count the number of times that you use the word classloader in your EJB world versus pre-EJB