EJB design: Understanding EJB as components, not an all-services API

  1. For 5 years now, EJB have been used in many projects, sometimes successfully, but also with great pain. Such a great pain was for developers, who had to fight with complex objects, learn a new technology and new design patterns, and for some project managers, who saw their applications getting heavier, slower, and more costly that ever to develop. So, one could naturally ask for the reason of such a failure. Is it a conspiracy from Sun to crash the economy ? Is an inability from Sun newbies to produce a consistent and effecient specification ? Or could it be a misunderstanding of what EJB are intended for ?

    To better the rationale for EJB, let’s first face problems that can arise with objects. If you consider the example of Car, Engine and Fuel objects, you will see that each object’s implementation is bound to another object interface : Car’s implementation references Engine’s interface, and Engine’s implementation references Fuel’s interface. This implies a dependency : a Car cannot be used without some Engine, and an Engine cannot without Fuel. Is such a dependency a problem ? No, because a Car doesn’t make sense without an Engine because it couldn’t be operational. Similary, an Engine doesn’t make sense without Fuel. So everything is ok, and that even does not preclude the Car (with its Engine), the Engine (with its Fuel), or the Fuel to be used independently in various contexts.

    Now let’s say that I want to protect my Engine run() command by some authentication system for instance. From a end (car-)user’s point of vue, that should only be a matter of modifying my object’s implementation, or even interface. From a developper/designer (car vendor) point of vue however, that means a lot of problems : what about customers that don’t want a car authentication system ? Should I write two (or more) Engine implementations ? This will probably be too costly and error-prone. So, as a car vendor, my solution is to design a general-purpose car framework able to assemble various car components like Engines, components that can be parameterized to use an authentication system or not. This way, I will be able to reuse my Engine components in different contexts by parameterizing my components instead of modifying their code. The words has been pronounced : “framework”, and “components”.

    A component framework helps to reuse parts of a system for use in different contexts, instead of multiplying them for specialization. In our case, we needed Engine to be pluggable and parameterizable as a component. The parameterized behavior of my component will be handled by the framework instead of the component, usally using code generation, but that's is not a definitive rule.

    In our example the Car component framework only handles one context variation (authentication) that I’m able to parameterize my Engine components for, but I could apply the same principle to handle a larger number of context variation types.

    So, should every object be a component ? The answer is the same as for “Would I need Engines to be components if my Engines didn’t need to be sometimes authenticated ?” No. A component answers the need for use of the same objects in various contexts. While your software don’t experience various contexts, you don’t need to componentize it. The corrolaire is : don’t make components before you need it.

    Now let’s get back to EJB. What are they intended for ? Persistence ? So why do they also provide security services ? Or distribution ? So why RMI wasn’t sufficient for that ? So maybe the intend of EJB is... let’s say... both persistence and distribution... and security... and transactions ? Doesn’t it sound strange ? What kind of “API” is that all-services API ? Is it what an API intended for ? Does it make sense ? Of course not.

    EJB is not an API. Is is a component framework. As such, it allows you to parameterize some parts of your system to allow you to reuse them in various contexts, without modifying them.

    Now let’s have a look at the rationale for all these EJB services. Here we can see that they provide a flexibility for two main categories of context variations :

    - the client call type can be secured or not, transactional or not, remote or local, synchronous or asynchronous, or even timed.
    - the component state can be empty of not, and persistent or not.

    This allow to handle 2 * 2 * 2 * 3 * 2 * 2, so around one hundred of context variations. To handle of these cases, my code won’t have to be either complex (handle all the different cases) or duplicated for specialization (writing 2 * 2 * 2 * 3 * 2 * 2 implementations). Again, this sound useful to me only because I know that I have to face to a number of these context variations. To handle only one, maybe two of these cases, a specific implementation might be more efficient than a general-purpose framework.

    A lot of people misunderstanding the purpose of EJB asked a lot for features that are completely opposed to the component paradigm. As they used EJB as objects, they asked for inheritance and fine-grained relationships. If they looked at EJB as components, they would probably want to avoid inheritance as a strong dependency, loosely specified dependency between components. To make the complex state of a component persist, they would also surely boosted the emergence a real persistence service for fined grained objects like JDO, that comes today after the battle.

    EJB are not perfect however. Nobody does. Even when considered as what they really are, EJB sometimes fails to provide proper code independency to context variations. For instance, the EJB persistence should allow a component to be persistent or not, without modyfing its code. This is definitely not the case : stateless, stateful session beans and entity beans cannot have the same code. Actually, there should be only one EJB implementation interface, not five.

    We saw that EJB failed to show themselves as a component framework, but the EJB specification itself is far from being innocent about that. When people asked to use explicit transaction demarcation or persistence for example, the specification answered to those people misundertanding and misusing EJB “You can do it if you want”, instead of “Use objects instead, not components”.

    The fact is that EJB failed to be (understood as) a component framework, and surrender by allowing car factories to patch the car framework when they want to build specific F1 engines. Unfortunaltely, it is getting worse and worse, with new EJB types (and code variations between them) in the latter EJB specifications. They also plan to support inheritance in a future release.
  2. That's a very profound statement. I'm not an expert but I do enjoy thinking about these matters. Here are some thoughts.

    The rarely mentioned Java Beans specs where intendend to be visual components in the sense you are describing. There's a little bit of an industry built around this technology but I don't know of anyone using it. This is not a surprise since Java has not faired too well on desktop. Nevertheless this at least provides some evidence that Sun has used the word component and delivered on it, at least once.

    This strict notion of a component is hard to carry over to the entreprise. It's hard to think of a component that functions well from one domain to another. A security component would work but what else works in this sense is not all that clear. Perhaps the word component is missused when applied to EJBs. From my perspective EJBs are hybrids between a true component and a framework. It's a category on it's own.

    EJBs have been missused due to complexity and the design-time-compression effect of aggressive shedules. This could have been aliviated by some very good rapid prototyping tools. This should have been a goal for Sun's strategy right from the start. EJB experiments/simulations take too long. Servlet technology has faired better since they lend themselves to easier prototyping. Trying to achieve rapid prototyping at the enterprise level is a challenge but this is where the time should be spent. in closing, EJB's or any future component techology that cannot be effectively planned for will be of limited value in a very competive market.

  3. Actually I discussed recently with some colleagues about this subject and found out that the "component" term isn't even understood the same way by many people. Some view them as the UML/UP point of vue, other view them as "big objects" or "objects containing objects". To me, that doesn't make sense as the "object" term is enough to define that, which is only a matter of granularity and encapsulation from the object paradigm.

    JavaBeans were effectively quite successful but as visual components only. This is because they provided a way to plug in visual containers and bind themselves (some remember the great work of VisualAge for Java in that domain). However, instead of decorating themselves (with additional generated code) depending on parameterized context variations, they had to be implemented as an "all-cases" support implementation, i.e. providing the expected behavior depending on their specified state/properties. This is not really the intent of components as I stated in my previous post, because this "all-case support" strategy still has an implementation overhead as it makes the code more complex to supports all the parameterizable aspects of the "component". Instead EJB focus on *one* implementation and decorate (generated additional code) to implement paramerized behavior suited to the application context.

    I would agree as your statement "it's hard to think of a component that functions well from one domain to another" if you're talking about a business component framework. Let me explain this : the fact is that standardizing business is very difficult, maybe even impossible. This has been tried by the IBM San Francisco framework, CORBA facilities, SAP, etc. and all failed to serve customers : either such business frameworks were unused because they didn't fit the customer business model/weren't flexible enough or they constrained the customer business model to fit their product. What I mean is that business-oriented frameworks can only be specified by the customers because what makes the customer make money is the specificity of the way it performs its business.

    This is the reason why, in my opinion component frameworks can only be successful if they are technical component frameworks. The only universal application context variations are technical variations (authentication, persistence, distribution, etc.).

    Unfortunately the fact is that, even technical only, EJB failed to be a component framework today, and destroyed, once again, the interest of the component idea in many minds.
  4. Your notion of a technical components is indeed very interesting. Implementing such constructions, at first glimpse, appears to require less effort than implementing the EJB specs. I would love to see something like that hit the market at some point.

    I can also envision building such technical compoments on top of EJBs -as a theoretical exercise, of course; such animals would crawl. This means that the pieces are there but do not quite deliver the goods in their current form.

    Alas, EJBs despite all their flaws, are in my humble opinion a step forward and do raise the bar for future technologies. On the other hand, once we get to component nirvana (if we ever get there), life would be pretty boring and the associated jobs would likely not pay well -the price of true simplicity.

    Thanks for the discussion.