Mountaineering in the Office?
Developers and managers often think of enterprise applications as insurmountable mountain peaks that only experts can climb. Much like mountain climbing, building a large-scale, enterprise-wide system is a daunting task, not for the faint of heart!
As a consultant, I have spent much time as an application architect, leading clients to the summit of an enterprise-wide system. In my experience, guiding an unskilled climbing party is dangerous. Similarly, building an enterprise-wide application without first educating your developers in distributed component technologies is a perilous undertaking.
JavaSoft has presented us with APIs such as the Java Naming and Directory Interface (JNDI) API, Java Servlet API and Java Message Service (JMS) API to help in our efforts. However, their new specification, Enterprise JavaBeans (EJB), holds the most promise to ease development of enterprise applications.
EJB's component-based development approach provides an exciting step toward enabling the average developer to make significant impacts for their organization quickly. EJB "empowers" the developer by hiding many of the complexities relating to persistence, transaction management, security, resource pooling, distributed object location, the integration of disparate technologies, and more. However, while any technology may tout its ease of use, it usually takes time to understand exactly how to best apply the technology to solve business problems.
The first issue on everyone's agenda is: "Where does this new technology fit into our existing architecture?" or even "Where does this new technology fit into an enterprise Java architecture?" While choosing a route in climbing isn't easy, neither is finding your way through the numerous APIs of the Java platform for the Enterprise.
This article seeks to educate you on EJB's role in the Java platform for the Enterprise. Since describing EJB's ability to integrate with disparate technologies would constitute a lengthy article by itself, I'll focus on explaining the role of EJBs in a purely Java-based application solution today. Figure 1 puts the Java Enterprise APIs into perspective. Welcome to the Westra Party. Let's begin our trek!
Trailhead: Enterprise JavaBeans
When guiding an inexperienced party, a mountain guide generally will take the path of least resistance to the top. Enterprise Java-Beans represents the path of least resistance to the corporate developer who wishes to build scalable, portable, enterprise applications quickly. As JavaBeans has led the component revolution for portable, client-side development, EJB looks to do the same for portable server-side component development. As stated before, EJB eases development for corporate developers by hiding the complexities of building applications with distributed architectures. Let's review some key concepts in the EJB specification that make it easy to use, then dig into EJB's role within the Java Enterprise APIs.
The Enterprise JavaBeans specification, supported by industry leaders such as IBM, AOL/Netscape, BEA Systems and Oracle, defines a component model for building n-tiered Java applications in a distributed architecture. The specification defines two types of components or EnterpriseBeans:
- SessionBeans: Components that contain business logic and maintain session with a particular client
- EntityBeans: Components that represent business entities and are inherently persistent
Thus a ShoppingCartBean that holds products a user wishes to purchase from a Web site would be a prime candidate for a SessionBean. Likewise, the OrderBean in this Web application would be an example of an EntityBean that may contain price information, order date and a shipping address while stored in the seller's database.
Apart from defining EnterpriseBeans, the central ingredient of the EJB specification's component model with respect to simplifying distributed systems development is the concept of a component execution environment. Such an environment typically consists of an EJB Server and EJB containers. JavaBean client components typically run within a visual container. Similarly, EJB containers allocate a process within their EJB Server for your server-side components (i.e., SessionBeans and EntityBeans) to execute. The container shelters your component from its runtime platform by managing all interactions with the operating system for the component. Thus, together, an EJB Server and its containers provide your components with access to runtime services such as persistence, distributed transaction management, threading and resource pooling .
Any vendor following the Enterprise Java-Beans specification can build EJB Server functionality into their products. For instance, database management systems, application servers, component transaction servers, transaction processing monitors and object transaction managers are all products that could include EJB Server functionality. Oracle's RDBMS, Novera JBusiness Application Server from Novera Software, Sybase's Jaguar Component Transaction Server and BEA System's M3 Object Transaction Manager, respectively, are products to watch now and in the future for EJB compliance.
The exciting thing about the EJB specification is that it sets a standard for server-side components to obtain distributed runtime services, much like the JavaBeans specification does for client-side beans.
Also, application components that utilize their container only for services are guaranteed interoperability when migrated to other EJB Servers provided by third-party vendors. As we'll see, EJB Server functionality relies heavily on the Java Enterprise APIs. With that quick overview, we've reached our first stop, Base Camp.
Base Camp: Java Enterprise Persistence APIs
At Base Camp we discover how database interface standards integrate with Enterprise JavaBeans. The three leading Java DB standards the JDBC 2.0, SQLJ and ODMG 2.0 Binding APIs cover three related types of persistence models. The JDBC 2.0 API provides an object interface to SQL database calls. The SQLJ specification defines the use of embedded SQL running on the JDBC API to provide portable stored procedures and data types. Last, the ODMG 2.0 Binding API provides for the transparent storage of Java objects to an object database. While the EJB specification doesn't require an EJB Server to implement a specific storage API, most EJB vendors to date have provided support for JDBC. They'll likely add support for the remaining two enterprise persistence APIs as demand increases.
The EJB specification provides two mechanisms for storing EntityBeans: bean-managed persistence and container-managed persistence. Bean-managed persistence requires you to perform your own database connections. You must also understand at least one of the three complex storage APIs discussed above or object serialization. This approach offers you flexibility, but neither utilizes an EJB Server's power nor provides truly portable business components. For instance, what if your bean-managed EntityBean, originally built to access an RDBMS, now needs to be reused in an application that stores the component in a serialized format?
To solve this problem and more, EJB provides container-managed persistence. Container-managed persistence relies on the EJB server to generate the appropriate code to store the EntityBean.
This component-based approach reduces development time by shielding you from writing complex storage code. It also promotes bean portability by not locking your EntityBeans into a particular storage scheme. The Java Enterprise Persistence APIs offer powerful options in data storage, while EJB's container-managed persistence simplifies development of database applications. What else does EJB offer to ease our trek?
Rest Stop: Java Transaction Service API
At this rest stop we'll review the Java Transaction Service to understand its relationship with Enterprise JavaBeans. The JTS is based on CORBA's OTS and provides an interface to manage distributed transactions to multiple resources with a two-phase commit protocol. Thus JTS provides EJB applications with the ability to perform distributed transactions across multiple databases and even promises to allow transactions spanning different EJB Servers! JTS provides important functionality, but EJB adds critical packaging or encapsulation that conceals the complexities of transaction management from application developers through container-managed transactions. With the latter, all transaction boundaries are formed implicitly by the container and the EJB Server. You can wire numerous EJBeans together to create complex business logic without having to code a single explicit transaction demarcation.
Component-based development techniques allow transaction rules to be declared at EJBean deployment without code modification. Transaction attributes can be declared at the bean level or they can be very granular, declared on a per-method basis. For example, an EJBean deployed with TX_SUPPORTS in your initial application may be redeployed using TX_REQUIRED by utilizing your EJB Server's deployment wizards to modify the component's properties! While EJB also offers bean-managed transactions, only the most experienced developers should attempt to use this capability. Custom bean-managed transactions carry serious liabilities such as limited portability and reusability, and complexity of development. Figure 2 lists valid transaction attributes.
Java Naming and Directory Interface API
"This mountain is enormous. Where are we anyway?"
Mountaineers often use a receiver device to calculate their locations automatically from the global positioning system (GPS). Just as a satellite can transparently locate your position for you, EJB Servers use the JNDI to easily locate distributed Enterprise JavaBeans. JNDI presents a single interface to multiple naming and directory services in your enterprise. With it you can connect to heterogeneous services such as LDAP, NIS and CORBA (COS) Naming, and to an RMI Registry.
Because the EJB specification requires the use of JNDI, you don't need to know, for instance, what naming service to use or that your ShoppingCartBean is running on your NT server while your OrderBean is running on your UNIX box. You simply code to a single interface and access all distributed components transparently. Also, redeploying your components to another location has no effect on your lookup code. However, keep in mind that redeploying them to another vendor's EJB Server may require lookup code changes if you haven't insulated your calls with sound, object-oriented techniques.
Java Remote Method Invocation
"Base Camp to Westra Party....Do you copy?"
Distributed communications is essential in mountaineering. At Base Camp we left behind a two-way radio and Hank, the radio operator, to inform us on important matters like dangerous weather conditions. Likewise, the ability to communicate with distributed objects is essential to scalable enterprise applications.
JavaSoft developed RMI to allow distributed communications between Java Virtual Machines in an object-oriented fashion. Objects implementing the java.io.Serializable interface can be transported via RMI without manual byte streams management, which is a leap beyond socket communications!
However, taking advantage of RMI can be tedious work. It begins with defining your remote implementation class. With RMI, a distributed object doesn't move and all access is through a remote interface that you must define as well. This contains a subset of its distributed object's methods, presenting only methods you want to call remotely on your distributed object. Next, a tool is used to generate skeletons and stubs from your remote implementation class. These classes utilize a marshaling scheme to inflate and deflate objects passed to and from your remote object. Now that your RMI classes (remote implementation class, remote interface, client stub and remote skeleton) are ready for deployment, you must perform routine chores, such as starting a bootstrap registry service and binding your distributed references with a unique name to the registry. To access your distributed objects you must code lookup calls to the java.rmi.Naming class, passing URLs as keys. To totally confuse the situation, you now wonder which lookup service to really use, the JNDI API or the java.rmi.Naming class!
EJB takes much of the tedium and confusion out of developing distributed objects. Your EJB objects must adhere to Java RMI rules, such as arguments and return values must be legal types, and you must define a remote interface for each SessionBean or EntityBean. However, EJB does conceal the need to perform bootstrap registry services, register your EJBeans and access numerous naming services to get a distributed reference. EJB Servers provide skeleton and stub generation for your EJBeans, as well as lifecycle management (activation and deactivation) of your components. Some products may even offer automatic generation of remote interfaces for your EJBeans. Finally, as stated earlier, the EJB specification prevents confusion over multiple naming services by requiring the use of JNDI to look up all components. The RMI Registry can be accessed via JNDI's API.
Why would you use regular RMI, if EJB hides much of RMI's complexities? The most compelling reason is that the current specification for EJB doesn't support shared, stateful services. The closest EJB has is a stateful SessionBean, but that exists only on a per-client basis. It can't be shared between multiple users. This is an area where coding an RMI server would be a suitable solution. For instance, you might use an RMI server as a shared service to load reference table data into memory only once.
From this example we can see that EJB is not a "be-all, end-all" solution to our needs. Other Java Enterprise APIs will directly impact our distributed architecture as well. In any event, the ability to communicate remotely is a necessity in our enterprise-wide solution, and working with EJB makes life even easier.
Java Message Service API
"Westra Party to Base Camp....I just received your message. Sorry, my com-link was turned off."
When a message is important, it must have guaranteed delivery, especially when climbers' lives are at stake. The need for guaranteed message delivery is common in distributed enterprise applications as well. In the Java platform for the Enterprise, the JMS guarantees message delivery through asynchronous communications based on messaging queuing, and publish and subscribe mechanisms. The JTS provides a degree of message guarantee in that it raises an exception if not all components in a transaction are accessed successfully. However, the current specification for Enterprise JavaBeans doesn't support asynchronous messaging. So if your enterprise-wide solution needs guaranteed messaging, choose an application server that supports not only EJB, but provides JMS support as well.
Java Servlet API
"Look what I found, an old ice ax!"
Climbing equipment is outdated every year; technically advanced products make old gear obsolete. The relation of Java servlets to Enterprise JavaBeans is similar. In mid-1997, JavaSoft released the Java Servlet API to define how Java servlets and Web servers communicate with one another and provide the first real use of server-side Java. To utilize servlets, your Web server must be Java-enabled and support the Java Servlet API. Most n-tiered Java applications currently in production have been built around servlet functionality. For these applications, customized servlets provided load balancing, fail-over, session management, database access, servlet-oriented security and business rules processing on a middle tier.
Much of the functionality just described has been replaced by EJB with the help of application servers. Application servers supporting the EJB specification allow you to define and execute business logic, session management and database access logic from within your SessionBeans and EntityBeans instead.
Is there a need to use servlets in an EJB implementation? Aren't they in opposition to each other? Yes...and Maybe. Just as a thrifty climber makes use of old equipment when he finds it, servlets remain an integral part of a distributed enterprise Java solution. Servlets are great for accessing EJBeans when a limitation prevents the remote invocation of the EnterpriseBean from a client. For instance, if you build an Internet application that is pure HTML, you'll have a problem calling your EJBeans from your browser.
Likewise, if corporate policy prevents using IIOP to cross its firewalls, servlets are a perfect choice to communicate directly with your EJBeans once the firewall is breached with an HTTP request. In your Java enterprise solution, servlets will move to more of a router and HTML builder/parser role, routing requests to the appropriate EJBean as well as dynamically building/parsing HTML pages from EJBean data. Move your database access and business rule processing into EJBeans, relieving servlets of these responsibilities.
On our journey up the mountain of distributed systems development, we looked at Enterprise JavaBeans' role in the Java platform for the Enterprise. With EJB, JavaSoft has provided the final piece of gear you need to build scalable, enterprise-wide systems! Previously released APIs of the Java platform for the Enterprise either supplement EJB's weaknesses or lay the foundation for EJB's strengths. EJB is the glue that provides a uniform bundling of the Java Enterprise APIs, increasing application reliability and scalability as well as guaranteeing portability, ease of use and interoperability across EJB Servers. The Java Enterprise APIs are a powerful set of interfaces, and with the help of tools from vendors such as Novera Software, BEA and IBM you'll be well equipped to build your enterprise-wide system quickly.
We came far this month, but we haven't reached the summit yet, nor have we covered this topic in detail. Look to
for more information about the Java Enterprise APIs. Happy trekking!
About the Author:
Jason Westra resides in Boulder, Colorado, where he is a senior consultant with the component-based development practice of CSC Consulting. He can be reached at [email protected]