BUY THIS BOOK

Safari Books Online

What is this?

Looking to Reprint this content?


Enterprise JavaBeans
Enterprise JavaBeans, Second Edition

By Richard Monson-Haefel

Cover | Table of Contents


Table of Contents

Chapter 1: Introduction
This book is about Enterprise JavaBeans (Versions 1.1 and 1.0), Java's new component model for enterprise applications. Just as the Java platform has revolutionized the way we think about software development, Enterprise JavaBeans promises to revolutionize the way we think about developing mission-critical enterprise software. It combines server-side components with distributed object technologies such as CORBA and Java RMI to greatly simplify the task of application development. It automatically takes into account many of the requirements of business systems: 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, and component transaction monitors (CTMs). It's particularly important to have a basic understanding of component transaction monitors, the technology that lies beneath EJB. In Chapter 2 and Chapter 3, we'll start looking at EJB itself and see how enterprise beans are put together. The rest of this book is devoted to developing enterprise beans for an imaginary business and discussing advanced issues.
It is assumed that you're already familiar with Java; if you're not, Exploring Java™ by Patrick Niemeyer and Josh Peck is an excellent introduction. This book also assumes that you're conversant in the JDBC API, or at least SQL. If you're not familiar with JDBC, see Database Programming with JDBC™ and Java™, by George Reese.
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 any vendor's relational database that has a JDBC driver. You don't have to code to a particular database implementation; just change drivers and you change databases. It's the same with Enterprise JavaBeans. Ideally, an Enterprise JavaBeans component, an enterprise bean, can run in any application server that implements the Enterprise JavaBeans (EJB) specification. This means that you can develop and deploy your EJB business system in one server, such as IBM's WebSphere, and later move it to a different EJB server, such as BEA's WebLogic or Gemstone/J. Implementation independence means that your business components are not dependent on the brand of server, which means there are more options before you begin development, during development, and after deployment.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Setting the Stage
Before defining Enterprise JavaBeans more precisely, let's set the stage by discussing a number of important concepts: distributed objects, business objects, and component transaction monitors.
Distributed computing allows a business system to be more accessible. Distributed systems allow parts of the system to be located on separate computers, possibly in many different locations, where they make the most sense. In other words, distributed computing allows business logic and data to be reached from remote locations. Customers, business partners, and other remote parties can use a business system at any time from almost anywhere. The most recent development in distributed computing is distributed objects. Distributed object technologies such as Java RMI, CORBA, and Microsoft's DCOM allow objects running on one machine to be used by client applications on different computers.
Distributed objects evolved from a legacy form of three-tier architecture, which is used in TP monitor systems such as IBM's CICS or BEA's TUXEDO. These systems separate the presentation, business logic, and database into three distinct tiers (or layers). In the past, these legacy systems were usually composed of a "green screen" or dumb terminals for the presentation tier (first tier), COBOL or PL/1 applications on the middle tier (second tier), and some sort of database, such as DB2, as the backend (third tier). The introduction of distributed objects in recent years has given rise to a new form of three-tier architecture. Distributed object technologies make it possible to replace the procedural COBOL and PL/1 applications on the middle tier with business objects. A three-tier distributed business object architecture might have a sophisticated graphical user interface (GUI), business objects on the middle tier, and a relational or some other database on the backend. More complex architectures are often used in which there are many tiers: different objects reside on different servers and interact to get the job done. Creating these n -tier architectures with Enterprise JavaBeans is particularly easy.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Enterprise JavaBeans: Defined
Sun Microsystems' 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.
Wow! Now that's a mouthful and 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:
Enterprise JavaBeans is a standard server-side component model for component transaction monitors.
We have already set the stage for this definition by briefly defining the terms distributed objects, server-side components, and component transaction monitors. To provide you with a complete and solid foundation for learning about Enterprise JavaBeans, this chapter will now expand on these definitions.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Distributed Object Architectures
EJB is a component model for component transaction monitors, which are based on distributed object technologies. Therefore, 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 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 very simple. Essentially, there are three parts to this architecture: the object server, the skeleton, and the stub.
The object server is the business object that resides on the middle tier. The term "server" can be a little confusing, but for our purposes the object on the middle tier can be called the "object server" to distinguish it from its counterparts, the stub and skeleton. The object server is an instance of an object with its own unique state. Every object server class has matching stub and skeleton classes built specifically for that type of object server. So, for example, a distributed business object called Person would have matching Person_Stub and Person_Skeleton classes. As shown in Figure 1.2, the object server and skeleton reside on the middle tier, and the stub resides on the client.
The stub and the skeleton are responsible for making the object server, which lives 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 DCOM all use their own RMI protocol. Every instance of the object server 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. The stub resides on the client machine and is connected via the network to the skeleton. The stub acts as the object server's surrogate on the client and is responsible for communicating requests from the client to the object server 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.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Component Models
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 packages, developers can create, assemble, and deploy components that conform to the EJB specification.
The original JavaBeans™, the java.beans package in the core Java API, 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. A lot of the literature has referred to EJB as an extension of the original JavaBeans, but this is a misrepresentation. Other than the shared name, and the fact that they are both Java component models, the two APIs serve very different purposes. EJB does not extend or use the original JavaBeans component model.
The original JavaBeans (the java.beans package) is intended to be used for intraprocess purposes, while EJB (the javax.ejb package) is designed to be used for interprocess components. In other words, the original JavaBeans was not intended for distributed components. JavaBeans can be used to solve a variety of problems, but is primarily used to build clients by assembling visual (GUI) and nonvisual widgets. It's an excellent component model, possibly the best component model for intraprocess development ever devised, but it's not a server-side component model. EJB is 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 interfaces and classes in the form of Java packages that must be used in a particular way to isolate and encapsulate a set of functionality. 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 spreadsheet that can be used in any GUI application according to the rules specified in the original JavaBeans component model. In EJB, a component might be a customer business object that can be deployed in any EJB server and used to develop any business application that needs a customer business object.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Component Transaction Monitors
The CTM industry grew out of both the ORB and the transaction processing monitor (TP monitor) industries. The CTM is really a hybrid of these two technologies that provides a powerful, robust distributed object platform. To better understand what a CTM is, we will examine the strengths and weakness of TP monitors and ORBs.
Transaction processing monitors have been evolving for about 30 years (CICS was introduced in 1968) and have become powerful, high-speed server platforms for mission-critical applications. Some TP products like CICS and TUXEDO may be familiar to you. TP monitors are operating systems for business systems whose applications are written in languages like COBOL. It may seem strange to call a TP monitor an "operating system," but because they control an application's entire environment, it's a fitting description. TP monitor systems automatically manage the entire environment that a business system runs in, including transactions, resource management, and fault tolerance. The business logic in TP monitors is made up of procedural applications that are often accessed through network messaging or remote procedure calls (RPC), which are ancestors of RMI. Messaging allows a client to send a message directly to a TP monitor requesting that some application be run with certain parameters. It's similar in concept to the Java event model. Messaging can be synchronous or asynchronous, meaning that the sender may or may not be required to wait for a response. RPC is a distributed mechanism that allows clients to invoke procedures on applications in a TP monitor as if the procedure was executed locally. The primary difference between RPC and RMI is that RPC is used for procedure -based applications and RMI is used for distributed object systems. With RMI, methods can be invoked on a specific object identity, a specific business entity. In RPC, a client can call procedures on a specific type of application, but there is no concept of object identity. RMI is object oriented; RPC is procedural.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
CTMs and Server-Side Component Models
CTMs require that business objects adhere to the server-side component model implemented by the vendor. A good component model is critical to the success of a development project because it defines how easily an application developer can write business objects for the CTM. The component model is a contract that defines the responsibilities of the CTM and the business objects. With a good component model, a developer knows what to expect from the CTM and the CTM understands how to manage the business object. Server-side component models are great at describing the responsibilities of the application developer and CTM vendor.
Server-side component models are based on a specification. As long as the component adheres to the specification, it can be used by the CTM. The relationship between the server-side component and the CTM is like the relationship between a CD-ROM and a CD player. As long as the component (CD-ROM) adheres to the player's specifications, you can play it.
A CTM's relationship with its component model is also similar to the relationship the railway system has with trains. The railway system manages the train's environment, providing alternate routes for load balancing, multiple tracks for concurrency, and a traffic control system for managing resources. The railway provides the infrastructure that trains run on. Similarly, a CTM provides server-side components with the entire infrastructure needed to support concurrency, transactions, load balancing, etc.
Trains on the railway are like server-side components: they all perform different tasks but they do so using the same basic design. The train, like a server-side component, focuses on performing a task, such as moving cars, not managing the environment. For the engineer, the person driving the train, the interface for controlling the train is fairly simple: a brake and throttle. For the application developer, the interface to the server-side component is similarly limited.
Different CTMs may implement different component models, just as different railways have different kinds of trains. The differences between the component models vary, like railway systems having different track widths and different controls, but the fundamental operations of CTMs are the same. They all ensure that business objects are managed so that they can support large populations of users in mission-critical situations. This means that resources, concurrency, transactions, security, persistence, load balancing, and distribution of objects can be handled automatically, limiting the application developer to a simple interface. This allows the application developer to focus on the business logic instead of the enterprise infrastructure.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Titan Cruises: An Imaginary Business
To make things a little easier, and more fun, we will attempt to 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: a cruise has cabins that are similar to hotel rooms, serves meals like a restaurant, offers various recreational opportunities, and 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 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 will give us an opportunity to develop enterprise beans like Ship, Cabin, TravelAgent, ProcessPayment, and so forth. 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 we have chosen this as the persistence layer.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
What's Next?
In order 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. Developing an understanding of the EJB architecture is the focus of the next two chapters.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 2: Architectural Overview
As you learned in Chapter 2, Enterprise JavaBeans is a component model for component transaction monitors, the most advanced type of business application server available today. To effectively use Enterprise JavaBeans, you need to understand the EJB architecture, so this book includes two chapters on the subject. This chapter explores the core of EJB: how enterprise beans are distributed as business objects. Chapter 3 explores the services and resource management techniques supported by EJB.
To be truly versatile, the EJB component design had to be smart. For application developers, assembling enterprise beans is simple, requiring little or no expertise in the complex system-level issues that often plague three-tier development efforts. While EJB makes it easy for application developers, it also provides system developers (the people who write EJB servers) with a great deal of flexibility in how they support the EJB specification.
The similarities among different component transaction monitors (CTMs) allow the EJB abstraction to be a standard component model for all of them. Each vendor's CTM is implemented differently, but they all support the same primary services and similar resource management techniques. The primary services and resource management techniques are covered in more detail in Chapter 3, but some of the infrastructure for supporting them is addressed in this chapter.
Enterprise JavaBeans server-side components come in two fundamentally different types: entity beans and session beans. A good rule of thumb is that entity beans model business concepts that can be expressed as nouns. For example, an entity bean might represent a customer, a piece of equipment, an item in inventory, or even a place. In other words, entity beans model real-world objects; these objects are usually persistent records in some kind of database. Our hypothetical cruise line will need entity beans that represent cabins, customers, ships, etc.
Session beans are an extension of the client application and are responsible for managing processes or tasks. A Ship bean provides methods for doing things directly to a ship but doesn't say anything about the context under which those actions are taken. Booking passengers on the ship requires that we use a Ship bean, but also requires a lot of things that have nothing to do with the Ship itself: we'll need to know about passengers, ticket rates, schedules, and so on. A session bean is responsible for this kind of coordination. Session beans tend to manage particular kinds of activities, for example, the act of making a reservation. They have a lot to do with the relationships between different enterprise beans. A TravelAgent session bean, for example, might make use of a Cruise, a Cabin, and a Customer—all entity beans—to make a reservation.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Enterprise Bean Component
Enterprise JavaBeans server-side components come in two fundamentally different types: entity beans and session beans. A good rule of thumb is that entity beans model business concepts that can be expressed as nouns. For example, an entity bean might represent a customer, a piece of equipment, an item in inventory, or even a place. In other words, entity beans model real-world objects; these objects are usually persistent records in some kind of database. Our hypothetical cruise line will need entity beans that represent cabins, customers, ships, etc.
Session beans are an extension of the client application and are responsible for managing processes or tasks. A Ship bean provides methods for doing things directly to a ship but doesn't say anything about the context under which those actions are taken. Booking passengers on the ship requires that we use a Ship bean, but also requires a lot of things that have nothing to do with the Ship itself: we'll need to know about passengers, ticket rates, schedules, and so on. A session bean is responsible for this kind of coordination. Session beans tend to manage particular kinds of activities, for example, the act of making a reservation. They have a lot to do with the relationships between different enterprise beans. A TravelAgent session bean, for example, might make use of a Cruise, a Cabin, and a Customer—all entity beans—to make a reservation.
The activity that a session bean represents is fundamentally transient: you start making a reservation, you do a bunch of work, and then it's finished. A session bean doesn't represent something in a database. Obviously, session beans have lots of side effects on the database: in the process of making a reservation, you might create a new Reservation by assigning a Customer to a particular Cabin on a particular Ship. All of these changes would be reflected in the database by actions on the respective entity beans. Session beans like TravelAgent, which is responsible for making a reservation on a cruise, can even access a database directly and perform reads, updates, and deletes to data. But there's no TravelAgent record in the database—once the reservation is made, it's done.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Using Enterprise Beans
Now that you actually have a bean to work with, let's look at how a client would work with a bean to do something useful. We'll start with the Cabin bean that was defined earlier. A cabin is a thing or place whose description is stored in a database. To make the example a little bit more real, imagine that there are other entity beans, including a Ship, Cruise, Ticket, Passenger, Employee, and so on.
Imagine that a GUI client needs to display information about a particular cruise, including the cruise name, the ship name, and a list of cabins. Using the cruise ID obtained from a text field, we can use some of our beans to populate the GUI with data about the requested cruise. Here's what the code would look like:
CruiseHome cruiseHome = ... getCruiseHome();
// Get the cruise id from a text field.
String cruiseID = textFields1.getText();
// Create an EJB primary key from the cruise id.
CruisePrimaryKey pk = new CruisePrimaryKey(cruiseID);
// Use the primary key to find the cruise.
Cruise cruise = cruiseHome.findByPrimaryKey(pk);
// Set text field 2 to show the cruise name.
textField2.setText(cruise.getName());
// Get a remote reference to the ship that will be used
// for the cruise from the cruise bean.
Ship ship = cruise.getShip();
// Set text field 3 to show the ship's name.
textField3.setText(ship.getName());

// Get a list of all the cabins on the ship as remote references
// to the cabin beans.
Cabin [] cabins = ship.getCabins();

// Iterate through the enumeration, adding the name of each cabin
// to a list box.
for (int i = 0; i < cabins.length; i++){
    Cabin cabin = cabins[i];
    listBox1.addItem(cabin.getName());
}
Let's start by getting a remote reference to the EJB home for an entity bean that represents a cruise. It's not shown in the example, but references to the EJB home are obtained using JNDI. Java Naming and Directory Interface ( JNDI) is a powerful API for locating resources, such as remote objects, on networks. It's a little too complicated to talk about here, but rest assured that it will be covered in subsequent chapters.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Bean-Container Contract
The environment that surrounds the beans on the EJB server is often referred to as the container. The container is more a concept than a physical construct. Conceptually, the container acts as an intermediary between the bean class and the EJB server. The container manages the EJB objects and EJB homes for a particular type of bean and helps these constructs to manage bean resources and apply primary services like transactions, security, concurrency, naming, and so forth, to the bean instances at runtime. Conceptually, an EJB server may have many containers, each of which may contain one or more types of enterprise beans. As you will discover a little later, the container and the server are not clearly different constructs, but the EJB specification defines the component model in terms of the container responsibilities, so we will follow that convention here.
Enterprise bean components interface with the EJB server through a well-defined component model. The EntityBean and SessionBean interfaces are the bases of this component model. As we learned earlier, these interfaces provide callback methods that notify the bean class of state management events in its life cycle. At runtime, the container invokes the callback methods on the bean instance when appropriate state management events occur. When the container is about to write an entity bean instance's state to the database, for example, it first calls the bean instance's ejbStore() method. This provides the bean instance with an opportunity to do some clean up on its state just before it's written to the database. The ejbLoad() method is called just after the bean's state is populated from the database, providing the bean developer with an opportunity to manage the bean's state before the first business method is called. Other callback methods can be used by the bean class in a similar fashion. EJB defines when these various callback methods are invoked and what can be done within their context. This provides the bean developer with a predictable runtime component model.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Summary
This chapter covered a lot of ground describing the basic architecture of an EJB system. At this point you should understand that beans are business object components. The home interface defines life-cycle methods for creating, finding, and destroying beans and the remote interface defines the public business methods of the bean. The bean class is where the state and behavior of the bean are implemented.
There are two basic kinds of beans: session and entity. Entity beans are persistent and represent a person, place, or thing. Session beans are extensions of the client and embody a process or a workflow that defines how other beans interact. Session beans are not persistent, receiving their state from the client, and they live only as long as the client needs them.
The EJB object and EJB home are conceptual constructs that delegate method invocations to the bean class from the client and help the container to manage the bean class. The client does not interact with the bean directly. Instead, the client software interacts with EJBObject and EJBHome stubs, which are connected to the EJB object and EJB homes respectively. The EJB object implements the remote interface and expands the bean class's functionality. The EJB home implements the home interface and works closely with the container to create, locate, and remove beans.
Beans interact with their container through the well-defined bean-container contract. This contract provides callback methods, the EJBContext, and the JNDI environment context (EJB 1.1 only). The callback methods notify the bean class that it is involved in state management event. The EJBContext and JNDI environment context provides the bean instance with information about its environment. The container-server contract is not well defined and remains proprietary at this time. Future versions of EJB may specify the container-server contract.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 3: Resource Management and the Primary Services
Chapter 2 discussed the basic architecture of Enterprise JavaBeans (EJB), including the relationship between the bean class, remote interfaces, the EJB object and EJB home, and the EJB server. These architectural components define a common model for distributed server-side components in component transaction monitors (CTMs).
One of the reasons CTMs are such great distributed object platforms is that they do more than just distribute objects: they manage the resources used by distributed objects. CTMs are designed to manage thousands, even millions, of distributed objects simultaneously. To be this robust, CTMs must be very smart resource managers, managing how distributed objects use memory and processing power. EJB recognizes that some of the resource management techniques employed by CTMs are very common, and it defines interfaces that help developers create beans that can take advantage of these common practices.
EJB CTMs are also great distributed object brokers. Not only do they help clients locate the distributed objects they need, they also provide many services that make it much easier for a client to use the objects correctly. CTMs commonly support six primary services: concurrency, transaction management, persistence, object distribution, naming, and security. These services provide the kind of infrastructure that is necessary for a successful three-tier system.
This chapter discusses both the resource management facilities and the primary services that are available to Enterprise JavaBeans.
One of the fundamental benefits of using EJB servers is that they are able to handle heavy workloads while maintaining a high level of performance. A large business system with many users can easily require thousands of objects—even millions of objects—to be in use simultaneously. As the number of interactions among these objects increase, concurrency and transactional concerns can degrade the system's response time and frustrate users. EJB servers increase performance by synchronizing object interactions and sharing resources.
There is a relationship between the number of clients connected and the number of distributed objects that are required to service them. As client populations increase, the number of distributed objects and resources required increases. At some point, the increase in the number of clients will impact performance and diminish throughput. EJB explicitly supports two mechanisms that make it easier to manage large numbers of beans at runtime: instance pooling and activation.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Resource Management
One of the fundamental benefits of using EJB servers is that they are able to handle heavy workloads while maintaining a high level of performance. A large business system with many users can easily require thousands of objects—even millions of objects—to be in use simultaneously. As the number of interactions among these objects increase, concurrency and transactional concerns can degrade the system's response time and frustrate users. EJB servers increase performance by synchronizing object interactions and sharing resources.
There is a relationship between the number of clients connected and the number of distributed objects that are required to service them. As client populations increase, the number of distributed objects and resources required increases. At some point, the increase in the number of clients will impact performance and diminish throughput. EJB explicitly supports two mechanisms that make it easier to manage large numbers of beans at runtime: instance pooling and activation.
The concept of pooling resources is nothing new. A commonly used technique is to pool database connections so that the business objects in the system can share database access. This trick reduces the number of connections needed, which reduces resource consumption and increases throughput. Pooling and reusing database connections is less expensive than creating and destroying connections as needed. Some CTMs also apply resource pooling to server-side components; this technique is called instance pooling. Instance pooling reduces the number of component instances, and therefore resources, needed to service client requests. In addition, it is less expensive to reuse pooled instances than to frequently create and destroy instances.
As you already know, EJB clients interact with the remote interfaces that are implemented by EJB objects. Client applications never have direct access to the actual bean. Instead, they interact with EJB objects, which wrap bean instances. Instance pooling leverages indirect access to beans to provide better performance. In other words, since clients never access beans directly, there's no fundamental reason to keep a separate copy of each bean for each client. The server can keep a much smaller number of beans around to do the work, copying data into or out of them as needed. Although this sounds like a resource drain, when done correctly, it greatly reduces the resources actually required at any one time.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Primary Services
There are many value-added services available for distributed applications. The OMG (the CORBA governing body), for example, has defined 13 of these services for use in CORBA-compliant ORBs. This book looks at six value-added services that are called the primary services, because they are required to create an effective CTM. The primary services include concurrency, transactions, persistence, distributed objects, naming, and security.
The six primary services are not new concepts; the OMG defined interfaces for a most of them in CORBA some time ago. In most traditional CORBA ORBs, services are add-on subsystems that are explicitly utilized by the application code. This means that the server-side component developer has to write code to use primary service APIs right alongside their business logic. The use of primary services becomes complicated when they are used in combination with resource management techniques because the primary services are themselves complex. Using them in combination only compounds the problem.
As more complex component interactions are discovered, coordinating these services becomes a difficult task, requiring system-level expertise unrelated to the task of writing the application's business logic. Application developers can become so mired in the system-level concerns of coordinating various primary services and resource management mechanisms that their main responsibility, modeling the business, is all but forgotten.
EJB servers automatically manage all the primary services. This relieves the application developers from the task of mastering these complicated services. Instead, developers can focus on defining the business logic that describes the system, and leave the system-level concerns to the CTM. The following sections describe each of the primary services and explain how they are supported by EJB.
Session beans do not support concurrent access. This makes sense if you consider the nature of both stateful and stateless session beans. A stateful bean is an extension of one client and only serves that client. It doesn't make sense to make stateful beans concurrent if they are only used by the client that created them. Stateless session beans don't need to be concurrent because they don't maintain state that needs to be shared. The scope of the operations performed by a stateless bean is limited to the scope of each method invocation. No conversational state is maintained.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
What's Next?
The first three chapters gave you a foundation on which to develop Enterprise JavaBeans components and applications. You should have a better understanding of CTMs and the EJB component model.
Beginning with Chapter 4, you will develop your own beans and learn how to apply them in EJB applications.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 4: Developing Your First Enterprise Beans
One of the most important features of EJB is that beans should work with containers from different vendors. That doesn't mean that selecting a server and installing your beans on that server are trivial processes. We'll start this chapter with a general discussion of how you select and set up a server.
The EJB server you choose should be compliant with the EJB 1.0 or EJB 1.1 specification. However, in the EJB 1.0 version of the specification, support for entity beans and container-managed persistence is optional. In EJB 1.1, support for entity beans is required. The first example in this chapter—and most of the examples in this book—assume that your EJB server supports entity beans and container-managed persistence. The EJB server you choose should also provide a utility for deploying an enterprise bean. It doesn't matter whether the utility is command-line oriented or graphical, as long as it does the job. The deployment utility should allow you to work with prepackaged enterprise beans, i.e., beans that have already been developed and archived in a JAR file. Finally, the EJB server should support an SQL-standard relational database that is accessible using JDBC. For the database, you should have privileges sufficient for creating and modifying a few simple tables in addition to normal read, update, and delete capabilities. If you have chosen an EJB server that does not support an SQL standard relational database, you may need to modify the examples to work with the product you are using.
To get the most from this chapter, it helps to have an IDE that has a debugger and allows you to add Java files to its environment. Several Java IDEs, like Symantec's Visual Cafe, IBM's VisualAge, Inprise's JBuilder, and Sun's Forte, fulfill this simple requirement. The debugger is especially important because it allows you to walk slowly through your client code and observe how the EJB client API is used.
Once you have an IDE set up, you need to include the Enterprise JavaBeans packages. These packages include javax.ejb and for EJB 1.0
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Choosing and Setting Up an EJB Server
One of the most important features of EJB is that beans should work with containers from different vendors. That doesn't mean that selecting a server and installing your beans on that server are trivial processes. We'll start this chapter with a general discussion of how you select and set up a server.
The EJB server you choose should be compliant with the EJB 1.0 or EJB 1.1 specification. However, in the EJB 1.0 version of the specification, support for entity beans and container-managed persistence is optional. In EJB 1.1, support for entity beans is required. The first example in this chapter—and most of the examples in this book—assume that your EJB server supports entity beans and container-managed persistence. The EJB server you choose should also provide a utility for deploying an enterprise bean. It doesn't matter whether the utility is command-line oriented or graphical, as long as it does the job. The deployment utility should allow you to work with prepackaged enterprise beans, i.e., beans that have already been developed and archived in a JAR file. Finally, the EJB server should support an SQL-standard relational database that is accessible using JDBC. For the database, you should have privileges sufficient for creating and modifying a few simple tables in addition to normal read, update, and delete capabilities. If you have chosen an EJB server that does not support an SQL standard relational database, you may need to modify the examples to work with the product you are using.
To get the most from this chapter, it helps to have an IDE that has a debugger and allows you to add Java files to its environment. Several Java IDEs, like Symantec's Visual Cafe, IBM's VisualAge, Inprise's JBuilder, and Sun's Forte, fulfill this simple requirement. The debugger is especially important because it allows you to walk slowly through your client code and observe how the EJB client API is used.
Once you have an IDE set up, you need to include the Enterprise JavaBeans packages. These packages include javax.ejb and for EJB 1.0 javax.ejb.deployment
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Developing an Entity Bean
There seems to be no better place to start than the Cabin bean, which we have been examining throughout the previous chapters. The Cabin bean is an entity bean that encapsulates the data and behavior associated with a real-world cruise ship cabin in Titan's business domain.
When developing an entity bean, we first want to define the bean's remote interface. The remote interface defines the bean's business purpose; the methods of this interface must capture the concept of the entity. We defined the remote interface for the Cabin bean in Chapter 2; here, we add two new methods for setting and getting the ship ID and the bed count. The ship ID identifies the ship that the cabin belongs to, and the bed count tells how many people the cabin can accommodate.
package com.titan.cabin;

import java.rmi.RemoteException;

public interface Cabin extends javax.ejb.EJBObject {
    public String getName() throws RemoteException;
    public void setName(String str) throws RemoteException;
    public int getDeckLevel() throws RemoteException;
    public void setDeckLevel(int level) throws RemoteException;
    public int getShip() throws RemoteException;
                   public void setShip(int sp) throws RemoteException;
                   public int getBedCount() throws RemoteException;
                   public void setBedCount(int bc) throws RemoteException; 
}
The Cabin interface defines four properties: the name, deckLevel, ship, and bedCount. Properties are attributes of a bean that can be accessed by public set and get methods. The methods that access these properties are not explicitly defined in the Cabin interface, but the interface clearly specifies that these attributes are readable and changeable by a client.
Notice that we have made the Cabin interface a part of a new package named com.titan.cabin. In this book, we place all the classes and interfaces associated with each type of bean in a package specific to the bean. Because our beans are for the use of the Titan cruise line, we place these packages in the
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Developing a Session Bean
Session beans act as agents to the client, controlling workflow (the business process) and filling the gaps between the representation of data by entity beans and the business logic that interacts with that data. Session beans are often used to manage interactions between entity beans and can perform complex manipulations of beans to accomplish some task. Since we have only defined one entity bean so far, we will focus on a complex manipulation of the Cabin bean rather than the interactions of the Cabin bean with other entity beans. In Chapter 7, after we have had the opportunity to develop other entity beans, interactions of entity beans within session beans will be explored in greater detail.
Client applications and other beans use the Cabin bean in a variety of ways. Some of these uses were predictable when the Cabin bean was defined, but most were not. After all, an entity bean represents data—in this case, data describing a cabin. The uses to which we put that data will change over time—hence the importance of separating the data itself from the workflow. In Titan's business system, for example, we will need to list and report on cabins in ways that were not predictable when the Cabin bean was defined. Rather than change the Cabin bean every time we need to look at it differently, we will obtain the information we need using a session bean. Changing the definition of an entity bean should only be done within the context of a larger process—for example, a major redesign of the business system.
In Chapter 1 and Chapter 2, we talked hypothetically about a TravelAgent bean that was responsible for the workflow of booking a passage on a cruise. This session bean will be used in client applications accessed by travel agents throughout the world. In addition to booking tickets, the TravelAgent bean also provides information about which cabins are available on the cruise. In this chapter, we will develop the first implementation of this listing behavior in the TravelAgent bean. The listing method we develop in this example is admittedly very crude and far from optimal. However, this example is useful for demonstrating how to develop a very simple stateless session bean and how these session beans can manage other beans. In Chapter 7, we will rewrite the listing method. This "list cabins" behavior is used by travel agents to provide customers with a list of cabins that can accommodate the customer's needs. The Cabin bean does not directly support the kind of list, nor should it. The list we need is specific to the TravelAgent bean, so it's the Travel- Agent bean's responsibility to query the Cabin beans and produce the list.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 5: The Client View
Developing the Cabin bean and the TravelAgent bean should have raised your confidence, but it should also have raised a lot of questions. So far, we have glossed over most of the details involved in developing, deploying, and accessing these beans. In this chapter and the ones that follow, we will slowly peel away the layers of the Enterprise JavaBeans onion to expose the details of EJB application development.
This chapter focuses specifically on the client's view of an EJB system. The client, whether it is an application or another bean, doesn't work directly with the beans in the EJB system. Instead, clients interact with a set of interfaces that provide access to beans and their business logic. These interfaces consist of the JNDI API and an EJB client-side API. JNDI allows us to find and access beans regardless of their location on the network; the EJB client-side API is the set of interfaces and classes that a developer uses on the client to interact with beans.
The best approach to this chapter is to read about a feature of the client view and then try to use that feature in the Cabin bean and TravelAgent bean client applications you worked with in Chapter 4. This will provide you with hands-on experience and a much clearer understanding of the concepts. Have fun, experiment, and you'll be sure to understand the fundamentals.
In Chapter 4, the client application started by creating an InitialContext, which it then used to get a remote reference to the homes of the Cabin and TravelAgent beans. The InitialContext is part of a larger API called the Java Naming and Directory Interface ( JNDI). We use JNDI to look up an EJB home in an EJB server just like you might use a phone book to find the home number of a friend or business associate.
JNDI is a standard Java extension that provides a uniform API for accessing a wide range of services. In this respect, it is somewhat similar to JDBC, which provides uniform access to different relational databases. Just as JDBC lets you write code that doesn't care whether it's talking to an Oracle database or a Sybase database, JNDI lets you write code that can access different directory and naming services, like LDAP, Novell Netware NDS, CORBA Naming Service, and the naming services provided by EJB servers. EJB servers are required to support JNDI by organizing beans into a directory structure and providing a JNDI driver, called a
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Locating Beans with JNDI
In Chapter 4, the client application started by creating an InitialContext, which it then used to get a remote reference to the homes of the Cabin and TravelAgent beans. The InitialContext is part of a larger API called the Java Naming and Directory Interface ( JNDI). We use JNDI to look up an EJB home in an EJB server just like you might use a phone book to find the home number of a friend or business associate.
JNDI is a standard Java extension that provides a uniform API for accessing a wide range of services. In this respect, it is somewhat similar to JDBC, which provides uniform access to different relational databases. Just as JDBC lets you write code that doesn't care whether it's talking to an Oracle database or a Sybase database, JNDI lets you write code that can access different directory and naming services, like LDAP, Novell Netware NDS, CORBA Naming Service, and the naming services provided by EJB servers. EJB servers are required to support JNDI by organizing beans into a directory structure and providing a JNDI driver, called a service provider, for accessing that directory structure. Using JNDI, an enterprise can organize its beans, services, data, and other resources in a large virtual directory structure, which can provide a very powerful mechanism for binding together normally disparate systems.
The great thing about JNDI is that it is virtual and dynamic. JNDI is virtual because it allows one directory service to be linked to another through simple URLs. The URLs in JNDI are analogous to HTML links. Clicking on a link in HTML allows a user to load the contents of a web page. The new web page could be downloaded from the same host as the starting page or from a completely different web site—the location of the linked page is transparent to the user. Likewise, using JNDI, you can drill down through directories to files, printers, EJB home objects, and other resources using links that are similar to HTML links. The directories and subdirectories can be located in the same host or can be physically hosted at completely different locations. The user doesn't know or care where the directories are actually located. As a developer or administrator, you can create virtual directories that span a variety of different services over many different physical locations.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The EJB Client-Side API
Enterprise bean developers are required to provide a bean class, two remote interfaces, and for entity beans, a primary key class. Of these types, the remote interfaces and primary key class are visible to the client, while the bean class is not. The remote interface, home interface, and primary key contribute to the client-side API in EJB. The methods defined in these types as well as the methods of their supertypes provide the mechanisms that clients use to interact with an EJB business system.
The following sections examine in more detail the home interface, the remote interface, and the primary key, as well as other types that make up EJB's client-side API. This will provide you with a better understanding of how the client-side API is used and its relationship with the bean class on the EJB server.
Enterprise JavaBeans 1.0 defines its distributed interfaces in terms of Java RMI. RMI assumes that both the client and server are Java applications, so it takes full advantage of Java types as arguments and return values. Enterprise JavaBeans 1.1 also defines its distributed interfaces in terms of Java RMI, but it enforces compliance with CORBA's interface, reference, and value types by requiring that only Java RMI-IIOP types be used. In other words, the underlying protocol can be anything that the vendor wants as long as it supports the types of interfaces and arguments specified by Java RMI-IIOP. In a future version of EJB, Java RMI-IIOP ( Java RMI over IIOP) will be the required programming model for accessing beans. Requiring partial support for the Java RMI-IIOP standard ensures that early Java RMI-IIOP adopters are supported and makes for a seamless transition for other vendors in the future.
To be CORBA-compliant, Java RMI-IIOP had to restrict the definition of interfaces and arguments to types that map nicely to CORBA. The restrictions are really not all that bad, and you probably won't even notice them while developing your beans, but it's important to know what they are. The next few paragraphs discuss the Java RMI programming model for both EJB 1.0 and EJB 1.1, and point out the additional restrictions placed on RMI-IIOP types after discussing the restrictions shared by traditional Java RMI and Java RMI-IIOP.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 6: Entity Beans
In Chapter 4, we started developing some simple enterprise beans, skipping over a lot of the details in the process. In this chapter, we'll take a thorough look at the process of developing entity beans. On the surface, some of this material may look familiar, but it is much more detailed and specific to entity beans.
Entity beans model business concepts that can be expressed as nouns. This is a rule of thumb rather than a requirement, but it helps in determining when a business concept is a candidate for implementation as an entity bean. In grammar school you learned that nouns are words that describe a person, place, or thing. The concepts of "person" and "place" are fairly obvious: a person bean might represent a customer or a passenger, and a place bean might represent a city or a port-of-call. Similarly, entity beans often represent "things": real-world objects like ships, cabins, and so on. A bean can even represent a fairly abstract "thing," such as a ticket or a reservation. Entity beans describe both the state and behavior of real-world objects and allow developers to encapsulate the data and business rules associated with specific concepts; a cabin bean encapsulates the data and business rules associated with a cabin, and so on. This makes it possible for data associated with a concept to be manipulated consistently and safely.
In Titan's cruise ship business, we can identify hundreds of business concepts that are nouns and therefore could conceivably be modeled by entity beans. We've already seen a simple Cabin bean in Chapter 4, and we'll develop a Ship bean in this chapter. Titan could clearly make use of a PortOfCall bean, a Passenger bean, and many others. Each of these business concepts represents data that needs to be tracked and possibly manipulated. Entities really represent data in the database, so changes to an entity bean result in changes to the database.
There are many advantages to using entity beans instead of accessing the database directly. Utilizing entity beans to objectify data provides programmers with a simpler mechanism for accessing and changing data. It is much easier, for example, to change a ship's name by calling
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Container-Managed Persistence
Container-managed entity beans are the simplest to develop because they allow you to focus on the business logic, delegating the responsibility of persistence to the EJB container. When you deploy the bean, you identify which fields in the entity are managed by the container and how they map to the database. Once you have defined the fields that will be automatically managed and how they map to the database, the container generates the logic necessary to save the bean instance's state automatically.
Fields that are mapped to the database are called container-managed fields. Container-managed fields can be any Java primitive type or serializable objects. Most beans will use Java primitive types when persisting to a relational database, since it's easier to map Java primitives to relational data types.
EJB 1.1 also allows references to other beans to be container-managed fields. The EJB vendor must support converting bean references (remote or home interface types) from remote references to something that can be persisted in the database and converted back to a remote reference automatically. Vendors will normally convert remote references to primary keys, Handle or HomeHandle objects, or some other proprietary pointer type, which can be used to preserve the bean reference in the database. The container will manage this conversion from remote reference to persistent pointer and back automatically.
The advantage of container-managed persistence is that the bean can be defined independently of the database used to store its state. Container-managed beans can take advantage of a relational database or an object-oriented database. The bean state is defined independently, which makes the bean more reusable and flexible across applications.
The disadvantage of container-managed beans is that they require sophisticated mapping tools to define how the bean's fields map to the database. In some cases, this may be a simple matter of mapping each field in the bean instance to a column in the database or of serializing the bean to a file. In other cases, it may be more difficult. The state of some beans, for example, may be defined in terms of a complex relational database join or mapped to some kind of legacy system such as CICS or IMS.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Bean-Managed Persistence
Bean-managed persistence is more complicated than container-managed persistence because you must explicitly write the persistence logic into the bean class. In order to write the persistence handling code into the bean class, you must know what type of database is being used and the how the bean class's fields map to that database.
Bean-managed persistence gives you more flexibility in how state is managed between the bean instance and the database. Entity beans that are defined by complex joins, a combination of different databases, or other resources such as legacy systems will benefit from bean-managed persistence. Essentially, bean-managed persistence is the alternative to container-managed persistence when the deployment tools are inadequate for mapping the bean instance's state to the database. It is likely that enterprise developers will use bean-managed persistence for creating custom beans for their business system.
The disadvantage of bean-managed persistence is that more work is required to define the bean. You have to understand the structure of the database and develop the logic to create, update, and remove data associated with an entity. This requires diligence in using the EJB callback methods such as ejbLoad() and ejbStore() appropriately. In addition, you must explicitly develop the find methods defined in the bean's home interface.
Another disadvantage of bean-managed persistence is that it ties the bean to a specific database type and structure. Any changes in the database or in the structure of data require changes to the bean instance's definition; these changes may not be trivial. A bean-managed entity is not as database-independent as a container-managed entity, but it can better accommodate a complex or unusual set of data.
To understand how bean-managed persistence works, we will modify the Ship bean to use bean-managed persistence. The nice thing about this change is that we do not need to modify any of the client's API. All the changes take place in the ShipBean class and the deployment descriptor.
The bulk of the source code for a bean-managed Ship bean is applicable to both EJB 1.1 and EJB 1.0. Changes to accommodate EJB 1.0 containers are indicated by comments in the source code. There are two types of changes required:
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The Life Cycle of an Entity Bean
To understand how to best develop entity beans, it is important to understand how the container manages them. The EJB specification defines just about every major event in an entity bean's life, from the time it is instantiated to the time it is garbage collected. This is called the life cycle, and it provides the bean developer and EJB vendors with all the information they need to develop beans and EJB servers that adhere to a consistent protocol. To understand the life cycle, we will follow an entity instance through several life-cycle events and describe how the container interacts with the entity bean during these events. Figure 6.2 illustrates the life cycle of an entity instance.
Figure 6.2: Entity bean life cycle
We will examine the life cycle of an entity bean and identify the points at which the container would call each of the methods described in the EntityBean interface. Bean instances must implement the EntityBean interface, which means that invocations of the callback methods are invocations on the bean instance itse