The promise of J2EE is great. Create applications against a standard API, and your application will run on multiple platforms, different application servers and different databases.
Linux, Unix, Windows, Mac, etc
Jboss, Sun AS, Geronimo, Weblogic, Websphere, etc
MySQL, PostgreSQL, JavaDB, Oracle, MS SQL, Sybase, etc
How does this promise deliver in reality?
EJBCA is a J2EE application that was first created for the EJB1 standard in 2001, later moved to EJB2, now considering moving to EJB3. EJBCA currently runs on all operating systems mentioned, on three applicaton servers and on more than five databases. It sure sounds like J2EE delivers on it's promise, but let's take a look behind the scenes.
I claim that J2EE (ejb2) has taken standardization a few miles down the road, but they stopped short of the realy hairy stuff, such as database mappings. Stopping there created a chance for vendors to add some vendor lock-in tactics, and created a maintenance nightmare for developers.
J2EE 1.4 is good, but not great!
What does it take to create support for a new application server?
EJBCA uses Xdoclet to aid in generating the standard J2EE deployment descriptors. This works very well, and the deployment descriptors, once tuned to comply with the standard works well on all application servers. When a change is made in the code, the new deployment descriptors are automatically generated at the next build. Then, unfortunately, there are the application server specific descriptors. The standard left out some information that it deemed server specific from the standard descriptors, and the application server vendors have taken this small finger and taken the chance to implement as much vendor lock-in as they can. Starting with the possibility to specify server specific options in the extra deployment descriptors, some vendors have even duplicated the information from the standard deployment descriptors. Xdoclet is not updated anymore with support for new application servers meaning that we have to create them manually. So what do we have:
ejb-jar.xml : automatically created, no problem
jboss.xml : still works to auto-generate with Xdoclet actually
weblogic-ejb-jar.xml : can generate a skeleton with Xdoclet that we have to edit manually
sun-ejb-jar.xml : can generate a skeleton with Xdoclet that we have to edit manually
ibm-ejb-jar*.xml : can generate a skeleton with Xdoclet, but we never tested this
There is some work involved maintaining these files, although the largest part of the work is when a new application server should be supported. It's not fun though to manually edit plenty of files with basically the same information as already present in ejbca-jar.xml. These files are large!
This is the really hairy stuff. Since it's complicated I can understand why the JCP thought it best to leave it up to the vendors, especially at that time in history when this was a rather fresh area.
Lets see what we have here:
jbosscmp-jdbc.xml : Jboss mapping file, relatively simple
sun-cmp-mappings.xml : Sun mapping file, realtively simple
Schema.dbxmi : Sun database schema file, truly awful
weblogic-cmp-rdbms.jar.xml : Weblogic mapping file, relatively simple
Ok you say, these four files can not be so hard to maintain manually? But when we support five different databases there are five times the above files. Now we are beyond what any normal developer can stand. Out of all these, Xdoclet can only help with Jboss. That's why EJBCA only supports Oracle on Weblogic and MySQL and JavaDB on Sun AS. Especially generating the Sun schema files is so gruesome that you don't want to support that for many databases.
Not only are there a huge amount of application server specific deployment descriptors, but there are also differences in how the application server responds to rather standard events. To take one example, when happens when you do a basic create on an entity bean and the object already exists, and this is done via a session bean facade?
Jboss throws DuplicateKeyException, seems logical
Weblogic throws a TransactionRolledbackException wrapping a DuplicateKeyException, ehm well ok
Glassfish v1 throws a ServerException, ok whatever
So we have to catch a little wider array of errors, or do some more wrapping in the session facade, so what? Just a little more work to the already increasing maintenance burden.
Adding support for many application servers and many databases for a widely available J2EE 1.4 application is no easy task. The initial development for adding a new server/database pair can range from one week to several weeks work. After this initial work maintaining all these xml files gives you plenty of additional work.
What about the future?
J2EE 5/EJB3
Spring/Hibernate
Which one of these new popular frameworks will ease the burden in the most efficient way?