EJB design: Vendor Independence
I'm designing an application that requires the highest level of vendor independence possible from the appserver perspective--there's always a customer who says, "Oooh, we don't like Vendor X".
Ideally, we would like to offer a range of choices for appserver vendors.
If I implement BMP rather than CMP (which I understand carries the risk of vendor lock-in) what will be the issues in trying to port the application to a new appserver?
Any thoughts or suggestions along these lines would be appreciated.
The best thing to do here is to use a DAO (Data Accesss Object) pattern with your BMP beans.
Basically, you write a base DAO object that does all the CRUD. Create, Delete, Lookup, Store / Update. Typically, I like to use a factory that returns the BASE DAO, driven by and EJB env property for the class name of the DAO impl class.
For example, say you have an OrderBMP. The order bean would use the Factory.getOrderDAO(ejbcontext.getProperty("OrderDAO.className") to get the proper DAO for the installation.
Typically DAOs are singleton.
The BaseOrderDAO implements all the methods it can in a platform independant way, it might be abstract.
Then you implement an Oracle9iOrderDAO, a TeraDBOrderDAO, etc satisfying all those things you need.
When you deliver to the customer, all that is needed is a single line change in the env entries for the bean in the deployment descriptor.
Look into XDoclet. We have developed a highly portable infrastructure using it.
Basically, you write the EJB implementation and annotate it using special JavaDoc tags and XDoclet generates the bean implementation, the interfaces and the deployment descriptors for your target app server. It supports quite a few app servers (WebSphere, WebLogic, JBoss, Orion, JRun, the RI, of course, and more) and you can extend it to support app servers not in their list.
The best part is you can code all CMPs in the EJB2.0 fashion (abstract class, abstract acessors), regardless of the EJB spec level in the target app server. XDoclet generates code for the accessors and declares the instance variables for the fields if the target container has EJB1.1, or, leaves them abstract if the target container has EJB2.0.
Oh, it also builds DAO, data objects and primary key classes :-)
If I was in your position, I'd use the session facade pattern exclusively. I'd also only use session beans (stateless if I could get away with it).
I'd steer clear of entity beans because they have a greater reliance on the quality of the container.
I'd farm out all business logic to classes with no EJB dependencies what-so-ever. You stateless session beans would be hollow "proxies" while the real work would be done with native java underneath.
You wouldn't get any data access assistance from the container, but wouldn't be reliant on the container for much either.
You may have formed another opinion by now, but those are my thoughts for what they're worth.
Derek C. Ashmore
(Architect for ThreadWorks)