The Source for Java Technology Collaboration
User: Password:



   

Component Inheritance in EJB 2.0 Component Inheritance in EJB 2.0

by David Musicant
10/25/2005

Contents
Just What Is So Bad about
Not Having Component Inheritance?
Getting Our Bearings: Picking Our Tools
   Components
   Component Inheritance
What Are We Trying to Solve with
Component-Oriented Programming (COP) that
Object-Oriented Programming (OOP) Cannot?
Our Implementation of
Component Inheritance in EJB 2.0
What is Missing from Our Solution?
Looking Forward:
Incorporating It into the Specification
   Defining Applications
   Changes to ejb-jar.xml
   Scenario One
   Scenario Two
Conclusion
Resources

Over the last few years, while Enterprise JavaBeans (EJB) has gained in fame, it has simultaneously received much criticism. Numerous articles and blogs have expounded on why EJBs should not be used, lamenting their poor design. Perhaps the biggest complaint has been that EJB does not allow component inheritance for entity beans. The EJB 2.0 specification itself appears to confirm this criticism, declaring "the data model for container-managed persistence does not currently support inheritance. Therefore, entity objects or value classes of different types cannot be compared." Despite this declaration, EJB 2.0 can support component inheritance.

Just What Is So Bad about Not Having Component Inheritance?

One of Sun's main goals in creating EJBs was to accomplish for Java enterprise software what ActiveX/COM had achieved for Microsoft's development platform. The first goal of the EJB specification is to make it possible to build applications from custom components used alongside components purchased from different vendors. Sound similar to COM and ActiveX? The specification aimed to take components even a step further and enable deploying the application and components onto multiple platforms.

However, without component inheritance and polymorphism, those components would be too rigid and unable to properly describe the business context of each potential customer. Take the example of a company that sells store components, such as ProductBean. The bean has a set of predefined attributes like productId. A customer, Small Company, Inc., wishes to add attributes and functions to better represent their current product schema. Without inheritance and polymorphism, their beans would be incompatible with the store components that expect ProductBeans. They would lose the ability to integrate custom and third-party software, and to properly represent their business rules.

Getting Our Bearings: Picking Our Tools

Components

In the world of component-oriented development, there is much disagreement over what constitutes a component and thus what component inheritance is, arising in part from confusion about the difference between objects and components. There are similarities between the two; for example, both have interfaces and types, can participate in inheritance and polymorphism, and result in instances within a system. This has led to the erroneous assumption that entity beans are objects (see the article "EJB Inheritance" for an example), but they are actually components that have and support instances.

Since entity beans are constituted by and acting through objects, it seems like entity beans violate one of the tenets of components; that they have no externally visible state. The entity bean component does not have an externally observable state; rather, the objects by which it is constituted have state. An entity bean component is not simply the object returned by beanHome.findByPrimaryKey(). It is the home, the remote and local interfaces, the bean class, the XML descriptor file, any remote stubs and any objects, and classes or other items used to constitute the component. This is why ejbHome methods can be implemented in the same class file as "EJBObject instance" methods. This distinction is what Clemens Szyperski calls "the separation of the immutable 'plan' from the mutable 'instances.'" (See Szyperski's Component Software: Beyond Object-Oriented Programming.)

The differences between objects and components start with their approaches to software. The object-oriented approach is concerned first with design and development, while the component-oriented approach aims towards deployment (see Stuart Halloway's Component Development for the Java Platform for more on this distinction). As a result, a component's type (as defined by the interfaces it supports) and its implementation are separated. The separation allows a deployed component to change its implementation, or code, without breaking its contract with other components. In contrast, once an object's class is defined in a class loader, it cannot be redefined in that class loader; the implementation becomes permanent for the runtime.

Comparing Objects and Components
Objects Components
  • Have a unique identity
  • Encapsulate/express state and behavior
  • Have behavior and structure defined by classes
  • Are designed (through classes) for development contexts
  • Are units of instantiation
  • Have no externally observable state
  • Have type and implementation separated
  • Conform to standards set by a component model
  • Are built for deployment contexts
  • Are units of independent deployment

Building on those attributes, a component is a typed, deployable unit of functionality that adheres to a contract of specified interfaces and deployment rules with a component model framework. A component has no observable state despite any instances or data it may create. Further, a component such as an entity bean is not simply its interfaces, EntityBean class, and descriptor files, but also any objects, code, or other resources created by the container in its deployment.

Component Inheritance

Inheritance actually consists of two concepts: inheritance and inclusion polymorphism. Inheritance is the incorporation of abstraction aspects in an interface or implementation by one entity of another. Polymorphism is the ability for one thing to appear in multiple forms depending on context, and the ability of different things to appear the same in a certain context. Inclusion polymorphism is more frequently referred to as sub-typing. For this article, we will use "component inheritance" to refer to the idea of both inheritance and inclusion polymorphism of components.

Component inheritance can be confusing and difficult to grasp for OOP developers due to choices in implementation and demarcation. Some implementations, such as ours, rely in part on object inheritance. Other choices might use delegation, proxies, or other devices that may not fit the object-oriented inheritance definition. The hierarchy mapping is also specified in a less overt manner. In Java's object inheritance, the relationship is clearly marked by the key word extends. Component inheritance might be declared in an XML file, as a metadata key, or via some other manner--it may not be evident in the code at all.

Components' separation of type and implementation offer a new inheritance paradigm for OO developers. In OO, if an object Magazine's class inherited from Product and was defined in a class loader, the class loader could not load a new Product implementation without breaking Magazine. Further, Magazine had to be compiled against Product code--Product's code had to be available at compile time. Components, on the other hand, do not require the base component's code at compile time. This is one of the most powerful advantages for components. A base component's implementation can be changed at runtime without breaking the inheritance relationship.

Component inheritance includes the ability to execute cross-type actions. Thus, if we have a base Employee component and the sub-types Manager and WorkerBee, we can ask the Employment "family":


//Give me all the employees in Department 2
Collection employees = 
   employeeHome.getEmployeesInDepartment( 
         new Integer( 2 ) 
);

and expect to get back a collection of both Manager and WorkerBee Employees.

Inclusion polymorphism works as it does for objects: components can be treated in the same manner and handled in the same context when treated as a base type. The implementation of the base component's inherited interface can be either overridden or utilized by the sub-type. Lastly, the base component has no knowledge of the sub-types that have inherited from it. This does not stop bounded inheritance, or the ability to restrict sub-types, but leaves this control in the hands of the deployer.

What Are We Trying to Solve with Component-Oriented Programming (COP) that Object-Oriented Programming (OOP) Cannot?

Why are EJBs components and not Plain Old Java Objects (POJOs)?

Many "enterprise" projects require numerous complex technologies, such as security architectures, transaction management, data manipulation, messaging, and other services. Custom solutions could be developed for these needs, but doing so would render most projects too expensive and unviable. Similar functionality has already been developed and tested by many groups. On the opposite end of the spectrum, a project could be fulfilled by an "off the shelf" application. However, this approach may not address the need for customization or combining functionality with existing software. Neither extreme is a perfect solution.

Component-oriented programming offers a balance between the extremes. A component-model framework gives companies the ability to combine custom software with tested, pre-developed software to provide services outside of the scope of a project or skills of their team. Components offer a great degree of customization on two levels:

  1. Purchased components can be configured and customized during deployment.
  2. Custom components, as units of independent deployment, can be used alongside third-party components.

A component can be deployed into numerous contexts and implementations of the model framework without code changes. This is enabled by loose coupling of components with services through adherence to interface contracts. An entity bean can use the same code (ejbStore()) to prepare instance data for persistence regardless of whether it will be stored in a database, XML file, email, or any other source.

Some programmers may want POJOs to replace EJBs due to a misconception about the purpose of EJBs, borne in part from the business context in which EJBs came to the industry. Sun needed to make sure the EJB architecture was adopted by vendors, and more importantly, give the vendors a market. While Sun wanted a new paradigm, they knew most companies would be unwilling to scrap their existing systems. Most were built on top of RDBMSes, and if Sun's new product had been incompatible, it would not have been a good business decision. Unfortunately, this resulted in too close of a relationship between EJBs and RDBMSes, both in design and in the minds of developers.

As a result, most resources on EJB speak of entity beans as though they were simply an object facade for database entries. Container-managed persistence is frequently regarded as synchronizing an entity bean with a database record (one example of this can be found in Enterprise JavaBeans, 3rd Edition, by Richard Monson-Haefel). While all of the popular EJB containers work only with databases, that is an implementation choice, not a specification requirement. Entity beans could represent emails persisted into email servers, files, XML, or some other entities we have yet to imagine. In fact, Sun's definition of EJBs makes no mention of data or databases. "The EJB architecture is a component architecture for the development and deployment of component-based distributed business applications."

Part of the problem also stems from shifting from OOP's development/compile-time focus to COP's deployment-oriented focus. Perhaps that is why components in general have not caught on in the world of Java like they did in Microsoft's world.

Pages: 1, 2, 3

Next Page » 

View all java.net Articles.

 Feed java.net RSS Feeds