Java EE Programming/Enterprise JavaBeans
EJB stands for Enterprise JavaBeans. Freshers should not confuse this with Java Beans of Core Java.
This page is about Enterprise JavaBeans 2.1. It also covers EJB 2.0, which is still in widespread use. Just as the Java platform has revolutionized the way we think about software development, Enterprise JavaBeans has revolutionized the way we think about developing mission-critical enterprise software. It combines server-side components with distributed object technologies, asynchronous messaging, and web services to greatly simplify the task of application development. It automatically takes into account many of the requirements of business systems, including security, resource pooling, persistence, concurrency, and transactional integrity.
This book shows you how to use Enterprise JavaBeans to develop scalable, portable business systems. But before we can start talking about EJB itself, we'll need a brief introduction to the technologies addressed by EJB, such as component models, distributed objects, asynchronous messaging, and web services. It's particularly important to have a basic understanding of component transaction monitors, the technology that lies beneath EJB.
It is assumed that you're already familiar with Java; if you're not, read Java Programming first. This book also assumes that you're conversant in the JDBC API, or at least in SQL. If you're not familiar with JDBC, see Java JDBC using SQLite.
One of Java's most important features is platform independence. Since it was first released, Java has been marketed as "write once, run anywhere." While the hype has gotten a little heavy-handed at times, code written with Sun's Java programming language is remarkably platform-independent. Enterprise JavaBeans isn't just platform-independent—it's also implementation-independent. If you've worked with JDBC, you know a little about what this means. Not only can the JDBC API run on a Windows machine or on a Unix machine, it can also access relational databases of many different vendors (DB2, Oracle, MySQL, SQLServer, etc.) by using different JDBC drivers. You don't have to code to a particular database implementation—just change JDBC drivers, and you change databases. It's the same with EJB. Ideally, an EJB component—an enterprise bean—can run in any application server that implements the EJB specification. This means that you can develop and deploy your EJB business system in one server, such as BEA's WebLogic, and later move it to a different EJB server, such as Pramati, Sybase EAServer, IBM's WebSphere, or an open source project such as Apache Geronimo, OpenEJB, JOnAS, or JBoss. Implementation independence means that your business components are not dependent on the brand of server, which gives you many more options before, during, and after development and deployment.
In addition to supporting distributed business objects, Enterprise JavaBeans supports asynchronous messaging. EJB 2.1 also allows enterprise beans to be exposed as web services, so that their methods can be invoked by other J2EE applications as well as applications written in other programming languages on a variety of platforms. Web services in EJB 2.1 supports both RPC-style and document-style messaging. Support for web services is based on a new web service API: JAX-RPC.
Object-oriented languages such as Java, C++, and C# are used to write software that is flexible, extensible, and reusable—the three axioms of object-oriented development. In business systems, object-oriented languages are used to improve development of GUIs, to simplify access to data, and to encapsulate the business logic. The encapsulation of business logic into business objects is a fairly recent focus in the information-technology industry. Business is fluid, which means that a business's products, processes, and objectives evolve over time. If the software that models the business can be encapsulated into business objects, it becomes flexible, extensible, and reusable, and therefore evolves as the business evolves.
A server-side component model may define an architecture for developing distributed business objects that combine the accessibility of distributed object systems with the fluidity of objectified business logic. Server-side component models are used on the middle-tier application servers, which manage the components at runtime and make them available to remote clients. They provide a baseline of functionality that makes it easy to develop distributed business objects and assemble them into business solutions.
Server-side components can also be used to model other aspects of a business system, such as presentation and routing. The Java servlet, for example, is a server-side component that is used to generate HTML and XML data for the presentation layer of a three-tier architecture. EJB 2.1 message-driven beans, which are discussed later in this book, are server-side components that can be used to consume and process asynchronous messages.
Server-side components, like other components, can be bought and sold as independent pieces of executable software. They conform to a standard component model and can be executed without direct modification in a server that supports that component model. Server-side component models often support attribute-based programming, which allows the runtime behavior of the component to be modified when it is deployed, without having to change the programming code in the component. Depending on the component model, the server administrator can declare a server-side component's transactional, security, and even persistence behavior by setting these attributes to specific values.
As an organization's services, products, and operating procedures evolve, server-side components can be reassembled, modified, and extended so that the business system reflects those changes. Imagine a business system as a collection of server-side components that model concepts such as customers, products, reservations, and warehouses. Each component is like a Lego™ block that can be combined with other components to build a business solution. Products can be stored in the warehouse or delivered to a customer; a customer can make a reservation or purchase a product. You can assemble components, take them apart, use them in different combinations, and change their definitions. A business system based on server-side components is fluid because it is objectified, and it is accessible because the components can be distributed.
Enterprise JavaBeans Defined
Oracle's definition of Enterprise JavaBeans is:
- "The Enterprise JavaBeans architecture is a component architecture for the development and deployment of component-based distributed business applications. Applications written using the Enterprise JavaBeans architecture are scalable, transactional, and multi-user secure. These applications may be written once, and then deployed on any server platform that supports the Enterprise JavaBeans specification."
That's a mouthful, but it's not atypical of how Sun defines many of its Java technologies—have you ever read the definition of the Java language itself? It's about twice as long. This book offers a shorter definition of EJB:
Enterprise JavaBeans is a standard server-side component model for distributed business applications.
What this means is the EJB offers a standard model for building server-side components that represent both business objects (customers, items in inventory, and the like) and business processes (purchasing, stocking, and so on). Once you have built a set of components that fit the requirements of your business, you can combine them to create business applications. On top of that, as “distributed” components, they don’t all have to reside on the same server: Components can reside wherever it’s most convenient: a Customer component "live" near the Customer database, a Part component can “live” near the inventory database, and a Purchase business-process component can “live” near the user interface: you can do whatever’s necessary for minimizing latency, sharing the processing load, or maximizing reliability.
Distributed Object Architectures
To understand EJB, you need to understand how distributed objects work. Distributed object systems are the foundation for modern three-tier architectures. In a three-tier architecture, as shown in Figure 1-1, the presentation logic resides on the client (first tier), the business logic resides on the middle tier (second tier), and other resources, such as the database, reside on the backend (third tier).
Figure 1-1. Three-tier architecture
All distributed object protocols are built on the same basic architecture, which is designed to make an object on one computer look like it's residing on a different computer. Distributed object architectures are based on a network communication layer that is really simple. Essentially, there are three parts to this architecture: the business object, the skeleton, and the stub.
The business object resides on the middle tier. It's an instance of an object that models the state and business logic of some real-world concept, such as a person, order, or account. Every business object class has matching stub and skeleton classes built specifically for that type of business object. For example, a distributed business object called
Person would have matching
PersonSkeleton classes. As shown in Figure 1-2, the business object and skeleton reside on the middle tier, and the stub resides on the client.
The stub and the skeleton are responsible for making the business object on the middle tier look as if it is running locally on the client machine. This is accomplished through some kind of Remote Method Invocation (RMI) protocol. An RMI protocol is used to communicate method invocations over a network. CORBA, Java RMI, and Microsoft .NET all use their own protocols. Every instance of the business object on the middle tier is wrapped by an instance of its matching skeleton class. The skeleton is set up on a port and IP address and listens for requests from the stub, which resides on the client machine and is connected via the network to the skeleton. The stub acts as the business object's surrogate on the client and is responsible for communicating requests from the client to the business object through the skeleton. Figure 1-2 illustrates the process of communicating a method invocation from the client to the server object and back. The stub and the skeleton hide the communication specifics of the RMI protocol from the client and the implementation class, respectively.
Figure 1-2. RMI loop
The business object implements a public interface that declares its business methods. The stub implements the same interface as the business object, but the stub's methods do not contain business logic. Instead, the business methods on the stub implement whatever networking operations are required to forward the request to the business object and receive the results. When a client invokes a business method on the stub, the request is communicated over the network by streaming the name of the method invoked, and the values passed in as parameters, to the skeleton. When the skeleton receives the incoming stream, it parses the stream to discover which method is requested, then invokes the corresponding business method on the business object. Any value that is returned from the method invoked on the business object is streamed back to the stub by the skeleton. The stub then returns the value to the client application as if it had processed the business logic locally.
The term component model has many different interpretations. Enterprise JavaBeans specifies a server-side component model. Using a set of classes and interfaces from the
javax.ejb package, developers can create, assemble, and deploy components that conform to the EJB specification.
The original JavaBeans™ is also a component model, but it's not a server-side component model like EJB. In fact, other than sharing the name "JavaBeans," these two component models are completely unrelated. In the past, a lot of the literature referred to EJB as an extension of the original JavaBeans, but it was a misrepresentation. The two APIs serve very different purposes, and EJB does not extend or use the original.
JavaBeans component model
JavaBeans is intended to be used for intra process purposes, while EJB is designed for inter process components. In other words, the original JavaBeans was not intended for distributed components. JavaBeans can be used to solve a variety of problems, but it is primarily used to build clients by assembling visual (GUI) and nonvisual widgets. It's an excellent component model, possibly the best one ever devised for intraprocess development, but it's not a server-side component model. EJB, on the other hand, is explicitly designed to address issues involved with managing distributed business objects in a three-tier architecture.
Given that JavaBeans and Enterprise JavaBeans are completely different, why are they both called component models? In this context, a component model defines a set of contracts between the component developer and the system that hosts the component. The contracts express how a component should be developed and packaged. Once a component is defined, it becomes an independent piece of software that can be distributed and used in other applications. A component is developed for a specific purpose but not a specific application. In the original JavaBeans, a component might be a push button or a spreadsheet that can be used in any GUI application according to the rules specified in the original JavaBeans component model. In EJB, there are several different types of components: components that represent entities in a database (entity beans) have a slightly different contract with their container than components that represent business processes (session beans). For example, a component might be a Customer business object, represented by an entity bean, that can be deployed in any EJB server and used to develop any business application that needs a customer business object. Another type of component might be a
MakePurchase object, represented by a session bean, that models what happens when a customer buys a particular product. (Although the act of making a purchase isn’t itself represented in a database, a purchase involves a complex interaction between a customer, a sales person, inventory, accounts receivable, and possibly other entities). The
MakePurchase object has a different contract with its container than the
Customer object, but it too can still be deployed in any EJB server and used in any business application that needs to support purchases. A third type of EJB, the MessageDrivenBean, has a slightly different contract with its container—but it, too, can be deployed in any EJB server.
Competing Component Models: Microsoft's .NET Framework
Enterprise JavaBeans did not appear out of nowhere; it is one of a number of component transaction monitors (CTMs), which in turn have their origin in older transaction processing monitors (such as Tuxedo) and Object Request Brokers. However, the most important competition for EJB is Microsoft’s .NET framework. .NET has its origins in the Microsoft Transaction Server (MTS), which was arguably the first commercially available CTM. MTS was later renamed COM+. Microsoft's COM+ is based on the Component Object Model (COM), originally designed for use on the desktop but eventually pressed into service as a server-side component model. For distributed access, COM+ clients use the Distributed Component Object Model (DCOM).
When MTS was introduced in 1996, it was an exciting development because it provided a comprehensive environment for business objects. With MTS, application developers could write COM components without worrying about system-level concerns. Once a business object was designed to conform to the COM model, MTS (and now COM+) took care of everything else, including transaction management, concurrency, and resource management.
COM+ has become part of Microsoft's new .NET Framework. The core functionality provided by COM+ services remains essentially the same in .NET, but the way it appears to a developer has changed significantly. Rather than writing components as COM objects, .NET Framework developers build applications as managed objects. All managed objects, and in fact all code written for the .NET Framework, depends on a Common Language Runtime (CLR). For Java-oriented developers, the CLR is much like a Java virtual machine (VM), and a managed object is analogous to an instance of a Java class; i.e., to a Java object.
The .NET Framework provides first class support web services via the SOAP (Simple Object Access Protocol) protocol, which enables business components in the .NET world to communicate with applications on any other platform written in any language. This can potentially make business components in .NET universally accessible, a feature that is not easily dismissed. In fact, .NET was the impetus that motivated Sun Microsystems to extend EJB and the rest of the J2EE platform to support web services. Microsoft's .NET platform represents the greatest threat to the dominance of the Java platform since the Java programming language was introduced in 1995.
Although the .NET Framework provides many interesting features, it falls short as an open standard. The COM+ services in the .NET Framework are Microsoft's proprietary CTM, which means that using this technology binds you to the Microsoft platform. If your company plans to deploy server-side components on a non-Microsoft platform, .NET is not a viable solution. In addition, the COM+ services in the .NET Framework are focused on stateless components; there's no built-in support for persistent transactional objects. Although stateless components can offer higher performance, business systems need the kind of flexibility offered by CTMs, which include stateful and persistent components.
Benefits of a Standard Server-Side Component Model
What does it mean to be a standard server-side component model? Quite simply, it means that you can develop business objects using the Enterprise JavaBeans component model and expect them to work in any application server that supports the complete EJB specification. This is a pretty powerful statement, because it largely eliminates the biggest problem faced by potential customers of Microsoft .NET products: fear of vendor "lock-in." With a standard server-side component model, customers can commit to using an EJB-compliant application server with the knowledge that they can migrate to a better server if one becomes available. Obviously, care must be taken when using proprietary extensions developed by vendors, but this is nothing new. Even in the relational database industry—which has been using the SQL standard for a couple of decades—optional proprietary extensions abound.
Having a standard server-side component model has benefits beyond implementation independence. A standard component model provides a vehicle for growth in the third-party products. If numerous vendors support EJB, creating add-on products and component libraries is more attractive to software vendors. The IT industry has seen this type of cottage industry grow up around other standards, such as SQL; hundreds of add-on products can now be purchased to enhance business systems with data that is stored in SQL-compliant relational databases. Report-generating tools and data-warehouse products are typical examples. The GUI component industry has also seen the growth of its own third-party products. A healthy market for component libraries already exists for GUI component models such as Sun's original JavaBeans component model.
Many third-party products for Enterprise JavaBeans exist today. Add-on products for credit card processing, legacy database access, and other business services have been introduced for various EJB-compliant systems. These types of products make development of EJB systems simpler and faster than the alternatives, making the EJB component model attractive to corporate IS and server vendors alike. The market for prepackaged EJB components is growing in several domains, including sales, finance, education, web-content management, collaboration, and other areas.
Titan Cruises: An Imaginary Business
To make things a little easier, and more fun, we will discuss all the concepts in this book in the context of one imaginary business, a cruise line called Titan. A cruise line makes a particularly interesting example because it incorporates several different businesses: it has ship cabins that are similar to hotel rooms, it serves meals like a restaurant, it offers various recreational opportunities, and it needs to interact with other travel businesses.
This type of business is a good candidate for a distributed object system because many of the system's users are geographically dispersed. Commercial travel agents, for example, who need to book passage on Titan ships will need to access the reservation system. Supporting many—possibly hundreds—of travel agents requires a robust transactional system to ensure that agents have access and that reservations are completed properly. Throughout this book, we will build a fairly simple slice of Titan's EJB system that focuses on the process of making a reservation for a cruise. This exercise will give us an opportunity to develop Ship, Cabin, TravelAgent, ProcessPayment, and other enterprise beans. In the process, you will need to create relational database tables for persisting data used in the example. It is assumed that you are familiar with relational database management systems and that you can create tables according to the SQL statements provided. EJB can be used with any kind of database or legacy application, but relational databases seem to be the most commonly understood database, so I have chosen this as the persistence layer.
To develop business objects using EJB, you have to understand the life cycle and architecture of EJB components. This means understanding conceptually how EJB's components are managed and made available as distributed objects.