Enterprise JavaBeans (EJBs)


EJBs are used for server-side transactions involving distrbuted objects. An enterprise bean can run on any application server that implements the EJB specification.

Plain old Javabeans (POJs) are not the same as EJBs. POJs cannot work with distributed components, rather, they can only work within the context of one server, primarily used to build GUI interfaces. EJBs manage distributed objects in an n-tier architecture.

A component model defines how a component is developed and packaged. Types of Java component models include Servlets, JSPs, and Applets.

In a distributed architecture, each business object has matching stub and skeleton classes. Using RMI protocols such as CORBA, Java RMI, and .NET, stubs and skeletons make business objects look as they were running locally on client machines. Skeleton class wrap business objects and are configured against specific ports and IP addresses, listening for requests from stubs. Stubs implement the same interface as their related business object, but contain networking logic rather than business logic. Requests are communicated over the network and values as parameters to skeletons.

Here is a generic business object with two methods:

public interface Invoice 
{
    public int getDuedate() throws Throwable;
    public String getVendor() throws Throwable;
}   

public class InvoiceServer implements Invoice 
{
    int duedate;
    String vendor;

    public InvoiceServer(String vendor, int duedate)
    {
        this.duedate = duedate;
        this.vendor = vendor;
    }

    public int getDuedate()
    {
        return duedate;
    }

    public String getVendor(){
        return vendor;
    }
}

Here is the stub:

import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.net.Socket;

public class Invoice_Stub implements Invoice 
{
    Socket socket;
    
    public Invoice_Stub() throws Throwable 
    {
       // Create a network connection to the skeleton. 
       socket = new Socket("localhost",9000);
    }


    public int getDuedate() throws Throwable 
    {
       // Stream the method name to the skeleton.
       ObjectOutputStream outStream = 
           new ObjectOutputStream(socket.getOutputStream());

       outStream.writeObject("duedate");
       outStream.flush();

       ObjectInputStream inStream = 
           new ObjectInputStream(socket.getInputStream());

       return inStream.readInt();
    }


    public String getVendor() throws Throwable 
    {

        // Stream the method name to the skeleton.
        ObjectOutputStream outStream = 
            new ObjectOutputStream(socket.getOutputStream());

        outStream.writeObject("vendor");
        outStream.flush();

        ObjectInputStream inStream = 
            new ObjectInputStream(socket.getInputStream());

        return (String)inStream.readObject();
    }
}

Here is the skeleton:

import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.net.ServerSocket;

public class Invoice_Skeleton extends Thread 
{
    InvoiceServer myServer;

    public Invoice_Skeleton(InvoiceServer server)
    {
        // Get a reference to the business object that this skeleton wraps.
        this.myServer = server;
    }
    public void run()
    {
      try 
      {

        // Create a server socket on port 9000.
        ServerSocket serverSocket = new ServerSocket(9000);

        // Wait for and obtain a socket connection from stub.
        Socket socket = serverSocket.accept();

        while (socket != null)
        {      

            // Create an input stream to receive requests from stub.
            ObjectInputStream inStream = 
                new ObjectInputStream(socket.getInputStream());

            // Read next method request from stub. Block until request is
            // sent.
            String method = (String)inStream.readObject();

            // Evaluate the type of method requested.
            if (method.equals("duedate"))
            {
                // Invoke business method on server object.
                int duedate = myServer.getDuedate();
                // Create an output stream to send return values back to
                // stub.
                ObjectOutputStream outStream = 
                    new ObjectOutputStream(socket.getOutputStream());
                // Send results back to stub.
                outStream.writeInt(duedate);
                outStream.flush();
            } 
            else if(method.equals("vendor"))
            {
                // Invoke business method on server object.
                String vendor = myServer.getVendor();

                // Create an output stream to send return values back to
                // the stub.
                ObjectOutputStream outStream = 
                    new ObjectOutputStream(socket.getOutputStream());

                // Send results back to stub.
                outStream.writeObject(vendor);
                outStream.flush();

            }
        }
      } 

      catch(Throwable t) 
      {
        t.printStackTrace();System.exit(0); 
      }

    }

    public static void main(String args [] )
    {
        // Obtain a unique instance Invoice.
        InvoiceServer invoice = new InvoiceServer("Richard", 36);
        Invoice_Skeleton skel = new Invoice_Skeleton(person);
        skel.start();
    }
}

The Invoice_Skeleton routes requests received from the stub to the business object, InvoiceServer. Essentially, the Invoice_Skeleton spends all its time waiting for the stub to stream it a request. Once a request is received, it is parsed and delegated to the corresponding method on the InvoiceServer. The return value from the business object is then streamed back to the stub, which returns it as if it was processed locally. Now that we've created all the machinery, let's look at a simple client that makes use of the Invoice:

public class InvoiceClient 
{
    public static void main(String [] args)
    {
        try 
        {
            Invoice invoice = new Invoice_Stub();
            int duedate = vendor.getDuedate();
            String vendor = vendor.getVendor();
            System.out.println(vendor+" is "+due+" years old");
        } 
        
        catch(Throwable t) 
        {
            t.printStackTrace();
        }
    }
}

This client application shows how the stub is used on the client. Except for the instantiation of the Invoice_Stub at the beginning, the client is unaware that the Invoice business object is actually a network proxy to the real business object on the middle tier.

RMI is the basis of distributed object systems and is responsible for making distributed objects location transparent. Location transparency means that a server object's actual location-usually on the middle tier-is unknown and unimportant to the client using it. In this example, the client could be located on the same machine or on a different machine very far away, but the client's interaction with the business object is the same. One of the biggest benefits of distributed object systems is location transparency. Although transparency is beneficial, you cannot treat distributed objects as local objects in your design because of the performance differences. This book will provide you with good distributed object design strategies that take advantage of transparency while maximizing the distributed system's performance.

When this book talks about the stub on the client, we will often refer to it as a remote reference to the business object. This allows us to talk more directly about the business object and its representation on the client.

Distributed object protocols such as CORBA, DCOM, and Java RMI provide a lot more infrastructure for distributed objects than the Invoice example. Most implementations of distributed object protocols provide utilities that automatically generate the appropriate stubs and skeletons for business objects. This eliminates custom development of these constructs and allows a lot more functionality to be included in the stub and skeleton.

Even with automatic generation of stubs and skeletons, the Invoice example hardly scratches the surface of a sophisticated distributed object protocol. Real world protocols like Java RMI and CORBA IIOP provide error and exception handling, parameter passing, and other services like the passing of transaction and security context. In addition, distributed object protocols support much more sophisticated mechanisms for connecting the stub to the skeleton; the direct stub-to-skeleton connection in the Invoice example is fairly primitive.

Real distributed object protocols, like CORBA, also provide an Object Request Broker (ORB), which allows clients to locate and communicate with distributed objects across the network. ORBs are the communication backbone, the switchboard, for distributed objects. In addition to handling communications, ORBs generally use a naming system for locating objects and many other features such as reference passing, distributed garbage collection, and resource management. However, ORBs are limited to facilitating communication between clients and distributed business objects. While they may support services like transaction management and security, use of these services is not automatic. With ORBs, most of the responsibility for creating system-level functionality or incorporating services falls on the shoulders of the application developer.

 

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 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 had 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.

JavaBeans is intended to be used for intraprocess purposes, while EJB 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 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 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. Other types of Java component models include Servlets, JSPs, and Applets.

 

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.

 

TP Monitors

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 applications 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 application runs in, including transactions, resource management, and fault tolerance. The business applications that run in TP monitors are written in procedural programming languages (e.g. COBOL and C) that are often accessed through network messaging or remote procedure calls (RPC). Messaging allows a client to send a message 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, which is the ancestor of RMI, 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.

TP monitors have been around for a long time, so the technology behind them is as solid as a rock; that is why they are used in many mission-critical systems today. But TP monitors are not object oriented. Instead, they work with procedural code that can perform complex tasks but has no sense of identity. Accessing a TP monitor through RPC is like executing static methods; there's no such thing as a unique object. In addition, because TP monitors are based on procedural applications, and not objects, the business logic in a TP monitor is not as flexible, extensible, or reusable as business objects in a distributed object system.

 

Object Request Brokers

Distributed object systems allow unique objects that have state and identity to be accessed across a network. Distributed object technologies like CORBA and Java RMI grew out of RPC with one significant difference: when you invoke a distributed object method, it's on an object instance, not an application procedure. Distributed objects are usually deployed on some kind of ORB, which is responsible for helping client applications find distributed objects easily.

ORBs, however, do not define an "operating system" for distributed objects. They are simply communications backbones that are used to access and interact with unique remote objects. When you develop a distributed object application using an ORB, all the responsibility for concurrency, transactions, resource management, and fault tolerance falls on your shoulders. These services may be supported by an ORB, but the application developer is responsible for incorporating them into the business objects. In an ORB, there is no concept of an "operating system," where system-level functionality is handled automatically. The lack of implicit system-level infrastructure places an enormous burden on the application developer. Developing the infrastructure required to handle concurrency, transactions, security, persistence, and everything else needed to support large user populations is a Herculean task that few corporate development teams are equipped to accomplish.

 

CTMs: The Hybrid of ORBs and TP Monitors

As the advantages of distributed objects became apparent, the number of systems deployed using ORBs increased very quickly. ORBs support distributed objects by employing a somewhat crude server-side component model that allows distributed objects to be connected to a communication backbone, but don't implicitly support transactions, security, persistence, and resource management. These services must be explicitly accessed through APIs by the distributed object, resulting in more complexity and, frequently, more development problems. In addition, resource management strategies such as instance swapping, resource pooling, and activation may not be supported at all. These types of strategies make it possible for a distributed object system to scale, improving performance and throughput and reducing latency. Without automatic support for resource management, application developers must implement homegrown resource management solutions, which requires a very sophisticated understanding of distributed object systems. ORBs fail to address the complexities of managing a component in a high-volume, mission-critical environment, an area where TP monitors have always excelled.

With three decades of TP monitor experience, it wasn't long before companies like IBM and BEA began developing a hybrid of ORBs and TP monitor systems, which we refer to as component transaction monitors. These types of application servers combine the fluidity and accessibility of distributed object systems based on ORBs with the robust "operating system" of a TP monitor. CTMs provide a comprehensive environment for server- side components by managing concurrency, transactions, object distribution, load balancing, security, and resource management automatically. While application developers still need to be aware of these facilities, they don't have to explicitly implement them when using a CTM.

The basic features of a CTM are distributed objects, an infrastructure that includes transaction management and other services, and a server-side component model. CTMs support these features in varying degrees; choosing the most robust and feature-rich CTM is not always as critical as choosing one that best meets your needs. Very large and robust CTMs can be enormously expensive and may be overkill for smaller projects. CTMs have come out of several different industries, including the relational database industry, the application server industry, the web server industry, the CORBA ORB industry, and the TP monitor industry. Each vendor offers products that reflect their particular area of expertise. However, when you're getting started, choosing a CTM that supports the Enterprise JavaBeans component model may be much more important than any particular feature set. Because Enterprise JavaBeans is implementation independent, choosing an EJB CTM provides the business system with the flexibility to scale to larger CTMs as needed. We will discuss the importance of EJB as a standard component model for CTMs later in this chapter.

 

Analogies to Relational Databases

This chapter spent a lot of time talking about CTMs because they are essential to the definition of EJB. The discussion of CTMs is not over, but to make things as clear as possible before proceeding, we will use relational databases as an analogy for CTMs.

Relational databases provide a simple development environment for application developers, in combination with a robust infrastructure for data. As an application developer using a relational database, you might design the table layouts, decide which columns are primary keys, and define indexes and stored procedures, but you don't develop the indexing algorithm, the SQL parser, or the cursor management system. These types of system- level functionality are left to the database vendor; you simply choose the product that best fits your needs. Application developers are concerned with how business data is organized, not how the database engine works. It would be waste of resources for an application developer to write a relational database from scratch when vendors like Microsoft, Oracle, and others already provide them.

Distributed business objects, if they are to be effective, require the same system-level management from CTMs as business data requires from relational databases. System- level functionality like concurrency, transaction management, and resource management is necessary if the business system is going to be used for large user populations or mission-critical work. It is unrealistic and wasteful to expect application developers to reinvent this system-level functionality when commercial solutions already exist.

CTMs are to business objects what relational databases are to data. CTMs handle all the system-level functionality, allowing the application developer to focus on the business problems. With a CTM, application developers can focus on the design and development of the business objects without having to waste thousands of hours developing the infrastructure that the business objects operate in.

 

EJB 2.0: Asynchronous Messaging

An asynchronous messaging system allows two or more applications to exchange information in the form of messages. A message, in this case, is a self-contained package of business data and network routing headers. The business data contained in a message can be anything-depending on the business scenario-and usually contains information about some business transaction. In enterprise messaging systems, messages inform an application of some event or occurrence in another system.

Messages are transmitted from one application to another on a network using message-oriented middleware (MOM). MOM products ensure that messages are properly distributed among applications. In addition, MOMs usually provide fault tolerance, load balancing, scalability, and transactional support for enterprises that need to reliably exchange large quantities of messages.

MOM vendors use different message formats and network protocols for exchanging messages, but the basic semantics are the same. An API is used to create a message, give it a payload (application data), assign it routing information, and then send the message. The same API is used to receive messages produced by other applications.

In all modern enterprise messaging systems, applications exchange messages through virtual channels called destinations. When sending a message, it's addressed to a destination, not a specific application. Any application that subscribes or registers an interest in that destination may receive that message. In this way, the applications that receive messages and those that send messages are decoupled. Senders and receivers are not bound to each other in any way and may send and receive messages as they see fit.

 

Java Message Service

Each MOM vendor implements its own networking protocols, routing, and administration facilities, but the basic semantics of the developer API provided by different MOMs are the same. It's this similarity in APIs that makes the Java Message Service possible.

 

Message-Driven Beans

EJB message-driven beans are used for routing asynchronous messages from one source to another.
All JMS vendors provide application developers with the same API for sending and receiving messages, and sometimes they provide a component model for developing routers that can receive and send messages. These component models, however, are proprietary and not portable across MOM vendors.

Enterprise JavaBeans 2.0 introduces a new kind of component, called a message-driven bean, which is a kind of standard JMS bean. It can receive and send asynchronous JMS messages, because it's co-located with other kinds of RMI beans (entity and session beans) it can also interact with RMI components.

Message-driven beans in EJB 2.0 act as an integration point for a EJB application, allowing other applications to asynchronous messages which can be captured and processed by an EJB application. This is an extremely important feature that will allow EJB applications to better integrate with legacy and other proprietary systems.

Message-driven beans are also transactional and required all the infrastructure associated with other RMI based transactional server-side components. Like other RMI based components, message-driven beans are considered business objects, which full fill an important role of routing and interpreting requests and coordinating the application of those requests against other RMI based components, namely enterprise beans. Message-driven beans are a good fit for the component transaction manager landscape and are an excellent addition to the Enterprise JavaBeans platform.

 

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.

 

Microsoft's .NET Framework

Microsoft was the first vendor to ship a CTM. Originally called the Microsoft Transaction Server (MTS), it 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 DCOM (Distributed Component Object Model).

When MTS was introduced in 1996, it was exciting because it provided a very 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+) would take care of everything else, including transaction management, concurrency, resource management-everything!

Recently, 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's appears to a developer changes significantly. Rather than writing components as COM objects, applications written for the .NET Framework are built 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 VM, and a managed object is very analogous to an instance of a Java class, i.e., to a Java object.

Although .NET Framework provides many interesting features, as an open standard, it falls short. The COM+ services in the .NET Framework are Microsoft's proprietary CTM, which means that using this technology binds you to the Microsoft platform. This may not be so bad, because .NET promises to work well, and the Microsoft platform is pervasive. In addition, the .NET Framework's support for SOAP (Simple Object Access Protocol) will enable business objects in the .NET world to communicate with objects on any other platform written in any language. This can potentially make business objects in .NET universally accessible, a feature that is not easily dismissed.

If, however, your company is expected 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 that include stateful and persistent components.

 

EJB and CORBA CTMs

Until the fall of 1997, non-Microsoft CTMs were pretty much nonexistent. Promising products from IBM, BEA, and Hitachi were on the drawing board, while MTS was already on the market. Although the non-MTS designs were only designs, they all had one thing in common: they all used CORBA as a distributed object service.

Most non-Microsoft CTMs were focused on, what was at the time, the more open standard of CORBA so that they could be deployed on non-Microsoft platforms and support non-Microsoft clients. CORBA is both language and platform independent, so CORBA CTM vendors could provide their customers with more implementation options . The problem with CORBA CTM designs was that they all had different server-side component models. In other words, if you developed a component for one vendor's CTM, you couldn't turn around and use that same component in another vendor's CTM. The component models were too different.

With Microsoft's MTS far in the lead by 1997 (it had already been around a year), CORBA-based CTM vendors needed a competitive advantage. One problem CTMs faced was a fragmented CORBA market where each vendor's product was different from the next. A fragmented market wouldn't benefit anyone, so the CORBA CTM vendors needed a standard to rally around. Besides the CORBA protocol, the most obvious standard needed was a component model, which would allow clients and third-party vendors to develop their business objects to one specification that would work in any CORBA CTM. Microsoft was, of course, pushing their component model as a standard-which was attractive because MTS was an actual working product-but Microsoft didn't support CORBA. The OMG (Object Management Group), the same people who developed the CORBA standard, were defining a server-side component model. This held promise because it was sure to be tailored to CORBA, but the OMG was slow in developing a standard-at least too slow for the evolving CTM market .

In 1997, Sun Microsystems was developing the most promising standard for server-side components called Enterprise JavaBeans. Sun offered some key advantages. First, Sun was respected and was known for working with vendors to define Java-based and vendor-agnostic APIs for common services. Sun had a habit of adopting the best ideas in the industry and then making the Java implementation an open standard-usually successfully. The Java database connectivity API, called JDBC, was a perfect example. Based largely on Microsoft's own ODBC, JDBC offered vendors a more flexible model for plugging in their own database access drivers. In addition, developers found the JDBC API much easier to work with. Sun was doing the same thing in its newer technologies like the JavaMail™ API and the Java Naming and Directory Interface (JNDI). These technologies were still being defined, but the collaboration among vendors was encouraging and the openness of the APIs was attractive.

Although CORBA offered an open standard, it attempted to standardize very low-level facilities like security and transactions. Vendors could not justify rewriting existing products such as TUXEDO and CICS to the CORBA standards. EJB got around that problem by saying it doesn't matter how you implement the low-level services; all that matters is all the facilities be applied to the components according to the specification-a much more palatable solution for existing and prospective CTM vendors. In addition, the Java language offered some pretty enticing advantages, not all of them purely technical. First, Java was a hot and sexy technology and simply making your product Java-compatible seemed to boost your exposure in the market. Java also offered some very attractive technical benefits. Java was more or less platform independent. A component model defined in the Java language would have definite marketing and technical benefits.

As it turned out, Sun had not been idle after it announced Enterprise JavaBeans. Sun's engineers had been working with several leading vendors to define a flexible and open standard to which vendors could easily adapt their existing products. This was a tall order because vendors had different kinds of servers including web servers, database servers, relational database servers, application server, and early CTMs. It's likely that no one wanted to sacrifice their architecture for the common good, but eventually the vendors agreed on a model that was flexible enough to accommodate different implementations yet solid enough to support real mission-critical development. In December of 1997, Sun Microsystems released the first draft specification of Enterprise JavaBeans, EJB 1.0, and vendors have been flocking to the server-side component model ever since.

 

Benefits of a Standard Server-Side Component Model

So 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 (EJB) component model and expect them to work in any CTM that supports the complete EJB specification. This is a pretty powerful statement because it largely eliminates the biggest problem faced by potential customers of CORBA-based CTM products: fear of vendor "lock-in." With a standard server-side component model, customers can commit to using an EJB-compliant CTM with the knowledge that they can migrate to a better CTM if one becomes available. Obviously, care must be taken when using proprietary extensions developed by vendors, but this is nothing new. Even in 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, then 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 like SQL, where hundreds of add-on products can be purchased to enhance business systems whose data is stored in SQL-compliant relational databases. Report generating tools and data warehouse products are typical examples. The GUI component industry has seen the growth of its own third-party products. A healthy market for component libraries already exists for GUI component models like Microsoft's ActiveX and Sun's original JavaBeans component models.

There are many examples of third-party product for Enterprise JavaBeans today Add-on products that provide services to EJB-compliant systems like credit card processing, legacy database access, and other business services have been introduced. 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 industry has market grow for prepackaged EJB components 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 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.

 

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 fo