| Page 1 of 3
next page »
The elegance of Java stems from how the language addresses a number of highly complex software engineering issues in a seemingly consistent and easy-to-use paradigm. While there are a few potholes that you need to be mindful of, most caused by the differences between primitives and objects, the power and reach of standard Java are testaments to the principle of simplicity that is embodied within it. Unfortunately, when it comes to Java's enterprise platform, J2EE strays considerably from J2SE in a number of areas, creating unnecessary additional complexity and ambiguity. To make matters worse, J2EE 1.3 (EJB 2.0) introduced self-inconsistencies.
J2EE's deviations fall into two categories: Structural and Behavioral. Structural deviations concern those areas where the implementation of a J2EE component requires a format that differs significantly from the implementation format of a similar J2SE component. Behavioral deviations concern those areas where substantial inconsistencies exist in the fundamental workings of J2EE, be they self-inconsistencies in J2EE components or inconsistencies with respect to analogous J2SE components.
In the case of J2EE's most high-profile technology, Enterprise JavaBeans (EJBs), these digressions can be mitigated by extending and enhancing EJBs into what I'll term BetterEJBs (see the pullout at the end of this article). Just as application server deployment tools can transparently generate EJB stubs and skeletons, tools can likewise be developed to auto-generate the necessary artifacts that are derivable from the BetterBean. The benefit: a BetterEJB developer needs only implement a single class, cutting down on development time, complexity, and the potential for errors while increasing understandability through the consolidation of information in a single location.
This article discusses a number of issues regarding the disparity between J2EE and J2SE, and spells out practical approaches and techniques that can be used to help return J2EE, specifically EJB, back to its Java roots. Additionally, this article illustrates the derivation of all supporting artifacts from the BetterBean, suggesting toolable functionality that could be realized to auto-generate the boilerplate constituent parts of the BetterEJB.
Structural Deviations
J2EE, and specifically EJB, has complicated the development of reusable functionality. Besides compromising Java's object-oriented nature, the format of the code has been made needlessly complex. When a data value object or utility object can be written in a single Java class, why does J2EE require that four (or possibly even six) files be written to make the enterprise-grade equivalent: an Entity or Session EJB? An EJB requires not only the Bean class, but also a Home Interface, a Remote Interface (optionally, a Local Home Interface and Local Remote Interface), and a deployment descriptor.
Given the distributed nature of EJB deployment, which is realized through application server-generated Stubs and Skeletons, it's reasonable for enterprise-grade functionality to require a client-facing interface in addition to the bean class. But, the necessity of any additional artifacts is overly complex and error prone.
Declarative Programming Gone Awry
By far the most egregious deviation is the EJB deployment descriptor. While declarative programming, through the use of runtime configuration files, is useful for separating environment-dependent information from hard-coded, core-component functionality, EJB has mistakenly taken declarative programming too far. Is it not central to the operation of a session bean whether it's stateful or stateless? It's not fundamental to the operation of a method whether or not it uses a database transaction. Considering that details such as these are integral to the functioning of the code, they shouldn't be alterable after compilation; these details should be explicit in the code and shouldn't be tweaked in deployment descriptors.
The following code illustrates how the designation of a BetterEJB as stateless or stateful is accomplished through the use of a marker interface in the definition of the BetterBean class, BetterBeanA:
1 public class BetterBeanA 2 implements StatelessBetterBean 3 { 4 ... 5 public Boolean foo() 6 { 7 return Boolean.TRUE; 8 } 9 }
Because BetterBeanA implements the StatelessBetterBean marker interface, the derived deployment descriptor is for a <session> bean with <session-type> of Stateless, as shown in the following snippet:
1 <session> 2 <ejb-name> 3 BetterBeanA 4 </ejb-name> 5 <home>BetterHomeInterfaceA</home> 6 <remote> 7 BetterRemoteInterfaceA 8 </remote> 9 <local-home> 10 BetterLocalHomeInterfaceA 11 </local-home> 12 <local> 13 BetterRemoteInterfaceA 14 </local> 15 <ejb-class>BetterStubA</ejb-class> 16 <session-type> 17 Stateless 18 </session-type> 19 </session>
The benefit of using marker interfaces is that it becomes possible to do build/compile-time checks on BetterBeanA, which can help eliminate the possibility of difficult-to-find runtime bugs or cryptic deployment-time errors.
Unnecessary Multitude of Interfaces
Why do EJBs require both a HomeInterface and a RemoteInterface (and optionally a LocalHomeInterface and LocalRemoteInterface)? Yes, the HomeInterface is used for locating the EJB implementation, while the RemoteInterface is the interface that's realized by the EJB implementation.
But, is it not possble for a single interface to perform both functions? Such a combination is achieved by the BetterInterface, as is shown by the interface for BetterBeanA, BetterInterfaceA:
1 public interface BetterInterfaceA 2 { 3 public static final String[2] 4 JNDI_LOOKUP_REFS 5 = {"BetterBeanA/LocalHome", 6 "BetterBeanA/Home"}; 7 ... 8 public Boolean foo(); 9 }
In addition to providing client-side signatures for all the methods implemented by BetterBeanA, this interface holds references for both remote EJB lookup and local EJB lookup. Passing these references to a lookup utility function (described later in this article) allows for retrieving either reference. In this way, only one interface is needed for both the lookup of and interaction with a BetterEJB.
Page 1 of 3
next page » |