Enterprise JavaBeans

Before we can jump into reading and writing EJB states to XML, we need a better understanding of Enterprise JavaBeans and the technologies required to use them.

Note

I've tried to give a fairly complete flavor for Enterprise JavaBeans within this chapter. However, a simple chapter cannot do this topic justice. Nor can we cover all the topics necessary for a sufficient understanding of EJBs. The interested reader is encouraged to read one of the resources listed in the "Further Reading" section of this chapter for a more complete understanding of EJBs.


EJB Architecture

Let's start with a refresher course in EJBs. For those readers proficient in EJBs, especially Bean-Managed Persistence Entity EJBs, feel free to skip ahead. For all others, read on as we introduce the basics of Enterprise JavaBeans.

Note

Note that the code in the following sections depends on the use of a Java Application Server such as BEA Systems WebLogic Server. A Java Application Server provides an execution environment for EJBs to run (live) in. You can download the latest version of WebLogic Server from the BEA Web site at http://www.beasys.com. For your convenience, WebLogic Server v4.51 is packaged on the CD and runs on Windows 95, 98, NT 4.0, 2000, and various UNIX platforms. See the BEA Web site for more information about WebLogic Server and all it can do.


EJBs are much like JavaBeans in that a client obtains a handle to an EJB and then uses it as if it were a regular Java object. However, that's where the similarities end. JavaBeans typically are created within the client and live out their lives there. Enterprise JavaBeans, on the other hand, live and execute on a Java Application Server, App Server for short, and the client has merely a reference to an object that implements a remote interface to the object. This remoted version of the EJB knows how to package up method call arguments, a process known as marshalling, and send the request over the wire to the server that then unmarshalls the parameters and uses Introspection to call the actual object instance. Actually there's much more to it than that: security, transactions, database support, and object lifecycle all come into the picture. Although a complete description of EJBs is beyond the scope of this chapter, we provide a number of excellent references for the interested reader. However, we will try to give enough details so that the process of persisting and restoring EJBs from XML makes some sense.

Three Types of EJBs

There are three types of EJBs:

  • Stateless session EJBs— These are by far the simplest of the three kinds of EJBs. Stateless session EJBs normally perform simple operations that are independent of prior method calls but need to execute on a server. For example, an EJB that computes pi to a given number of decimal places or returns the exponential (!) value of a given input are both stateless session EJBs. Any method that does not need to know or use information from a prior method call is typically a stateless session EJB. Stateless session EJBs can be, and typically are, shared by multiple clients.

  • Stateful session EJBs— These EJBs remember their conversational state from method call to method call. Stateful session EJBs are most like their JavaBeans cousins in that they remember what has happened previously. Call center EJBs, simple shopping cart EJBs, and anything where state needs to be maintained are examples of stateful session EJBs. Although stateful session EJBs can be shared, they typically are not. Anyone who has bought an item online has most likely encountered a stateful session EJB.

  • Entity EJBs— These are by far the most complex of the EJB types. Entity EJBs are in-memory representations of the state of some persistent object such as a customer's credit card or bank balance. Entity EJBs are objects that not only store state but persist that state to some backing storage such as a file or a database. We focus on entity EJBs in this chapter.

Entity EJBs would be difficult enough, but to make matters slightly worse, they come in two distinct flavors: Container-Managed Persistence (CMP) and Bean-Managed Persistence (BMP)Beans.

Before we get into the specifics of CMP and BMP, a little more background on EJB is in order.

Java Application Server Environments

Enterprise JavaBeans live and function within what is typically called a Java Application Server. Java Application Servers provide an execution environment for many objects, including EJBs. Some of the most common objects supported in an App Server are

  • Servlets— Server-side versions of client applets that can be run on the server as required to meet client need. We cover Servlets in detail in Chapter 9, "Servlets and XML."

  • Java Server Pages— More commonly called JSPs, Java Server Pages are HTML pages that can contain Java code and are dynamic in nature. JSPs allow the developer to have the best of both Java and HTML and are compiled on-the-fly into Servlets and then executed by the App Server when called for.

  • Java Messaging Services— More often called JMS, Java Messaging Services provide message-oriented middleware: that is, message passing between two Java applications.

  • Database Support— Support or drivers for common databases such as Oracle, Sybase, Microsoft SQL Server and so on are often provided by an App Server.

  • Other Support Services— In addition to the previously mentioned services, App Servers typically provide other less often used services such as startup classes, timing services, security, and so on.

  • EJB Execution Environment— For an EJB to execute correctly, a number of additional services are provided by an App Server. We will examine each in some detail in the next section, but some of the most important are

    • Transaction Support— EJBs execute transactions and, as such, support for transaction commit and rollback must be provided.

    • Lifecycle Services— EJBs come and go, and need to be created, pooled, and destroyed. App Servers provide for these features.

    • Naming and Object Lookup Services— Since EJBs live in a remote environment, we need to be able to find a given EJB, typically via JNDI, which we will examine briefly.

  • Object Persistence— EJBs can be persisted to secondary storage. This is one of the main differences between an EJB and a run-of-the-mill JavaBean. In fact, two forms of object persistence are provided by Application Servers: Container-Managed Persistence (CMP) and Bean-Managed Persistence (BMP).

All in all, EJB support is provided within the context of an EJB container. Containers wrap all the aforementioned services into a single lump defined by the EJB 1.0.1 specification. Containers provide infrastructure for all the services required by an EJB and wrap that infrastructure around the actual implementation of a bean to provide an execution environment. Many flavors of containers exist. BEA Systems WebLogic Server provides containers for persisting bean state to files and databases. Other vendors provide containers for complex database interaction, object-oriented databases, and so on.

Before we move on, let's examine the general process of EJB and App Servers. Figure 8.1 shows a big-picture view of an App Server showing how applets, Java clients, CORBA clients, and browser clients all access server services using various protocols such as HTTP, HTTPS, RMI, and IIOP. Many of these clients, particularly the Java clients, but perhaps CORBA clients as well, either directly or indirectly access JavaBeans and EJBs via Servlets, or other server-side applications. And each EJB that comes wrapped in a container can use container services such as transaction or security services support. Let's look at Remote Method Invocation, so we can better understand how EJBs are remoted.

Figure 8.1. The big picture for Java Application Server environments.


Figure 8.2 shows what typically happens when a class calls a method on another class. Figure 8.3 shows the same class being called via Remote Method Invocation, or RMI. With RMI, a class is split into two parts, using a tool such as the RMIC—the RMI Compiler. The two parts are typically called the Stub and the Skeleton. The Stub represents the interface to the class as it was originally known and is used by the client to invoke methods on the remote instance. The Skeleton receives the remote calls and translates them back to local calls on the actual class instance.

Figure 8.2. Normal procedure call.


Figure 8.3. Remote procedure calls using RMI.


EJBs are remoted in almost an identical fashion with one difference: There are two remoted interfaces for an EJB. The first handles lifecycle services (create, remove, find, and so on) for EJBs and the second interfaces to the remote instance of an EJB itself.

Figure 8.4 shows more of a client view of using an EJB. The client first requests a handle to the home interface of the bean, using Java Naming and Directory Interface (more on JNDI shortly). The client then uses the home interface to find an existing bean or create a new instance of a bean. The home interface then returns a remote stub that represents the bean currently being executed with the App Server. The client application then uses the bean's remote stub to call the bean's business methods normally.

Figure 8.4. The client view of EJB.


Let's examine the home interface and EJB lifecycle services in more detail.

Home Interface and Lifecycle Services

The home interface of a bean provides what are typically termed lifecycle services. Normally developers take lifecycle services for granted, using the new operator to create new instances of objects and letting the Java Virtual Machine destroy these objects when they are no longer referenced. However, since EJBs live within a remote App Server, simply setting a reference to null or exiting enclosing scope will not delete an entity EJB. Entity EJB Objects might exist, for example, within a database and not be referenced by any running application. Or instances may need to be created or removed. All these services are provided by the Appli-cation Server and available through the home interface. In a nutshell, the home interface provides methods for

  • Creating EJBs with no initial state

  • Creating EJBs using specified initial values

  • Finding existing instances of EJBs

  • Providing meta-data about the EJB itself

  • Providing methods for removing a specific instance of an EJB, or all similar instances

  • Sharing by all clients using the same type of EJB

  • Using a Naming Service, such as JNDI

  • Extending javax.ejb.EJBHome

Remote Interface

The second interface of interest within the EJB architecture is the remote interface. The remote interface, which wraps normal business methods, is the interface most clients are interested in. The remote interface provides access to the EJB's business methods and typically extends javax.ejb.EJBOBject and java.rmi.Remote. The remote interface is also responsible for marshalling arguments to the remote server and unmarshalling returned results.

Trust me, we are close to an actual example of persisting an EJB to XML, but first there are a few more items we need to cover. The first is the Java Naming and Directory Interface (JNDI).

Java Naming and Directory Interface (JNDI) Basics

Before we can do anything with an EJB, we need to be able to obtain a handle to an instance of it. With regular JavaBeans this was easy; we simply created an instance of the bean and started using it, perhaps storing and retrieving state values using XML. However, since Enterprise JavaBeans live on a remote App Server, we need to obtain a handle to a remote instance of the EJB and for this we use the Java Naming and Directory Interface (JNDI). JNDI serves two functions: storing references into existing objects in a JNDI tree, typically called binding an object, and returning previously bound objects, typically called object lookup. We won't go into the process of binding an EJB into a JNDI tree. JNDI trees are hierarchical in nature and can contain complete hierarchies of objects, since binding is most often configured in a vendor specific at startup. However, we do need to understand how to perform object lookups. Listing 8.9 shows a portion of an EJB client, the portion that uses JNDI to find the home interface of an object.

Note

It should be noted that the JNDI actually specifies an interface and not an implementation. Typically, Application Server vendors such as BEA and IBM provide the necessary implementation. This is a fine distinction, but an important one. Sun now also provides a reference implementation that can be freely downloaded from http://www.javasoft.com.


Code Listing 8.9. Using JNDI to Look Up an Object
 1:     Hashtable   env = new Hashtable();
 2:     env.put(Context.INITIAL_CONTEXT_FACTORY,
 3:             "weblogic.jndi.WLInitialContextFactory");
 4:     env.put(Context.PROVIDER_URL, "t3://localhost:7001");
 5:     try {
 6:         InitialContext   ic = new InitialContext(env);
 7:         AlarmClockHome   home =
 8:                 (AlarmClockHome) ic.lookup("AlarmClock");
 9:     } catch(...)
10:    // etc

Lookups using JNDI start by creating a Hashtable object. A Properties object would have worked as well. You then insert values into it representing the context we want to create, in lines 1–4, and create an InitialContext() object. The InitialContext() object effectively tells JNDI where to look for objects. We then use the initial context to look up an object previously bound, most likely at boot time, by the App Server. An important thing to note is that the values placed into the Hashtable are dependent on the App Server. The values shown work fine for WebLogic Server version 4.5.1. Other App Servers will require other configuration values.

Once we have our context, we get handles to objects and continue on our way happily looking up objects.

What Listing 8.9 ultimately returns is a reference to the home interface for an EJB. We can then use this interface like any other object, calling its methods normally. Listing 8.10 shows a complete client that exercises JNDI to find the AlarmClock home interface and then creates two instances of alarms (lines 21 and 23–24). It also deletes one of the instances using the remove method (line 42). With the exception of the original lookup and performing remove operations, an EJB works just like any other object.

Code Listing 8.10. Client.Java—Using a BMP-Managed EJB
 1: package sams.chp8.bmp;
 2:
 3: import java.util.*;
 4: import javax.naming.*;
 5: import javax.ejb.*;
 6: import java.rmi.*;
 7:
 8: public class Client {
 9:     public static void main(String args[]) {
10:         Hashtable   env = new Hashtable();
11:         env.put(Context.INITIAL_CONTEXT_FACTORY,
12:                 "weblogic.jndi.WLInitialContextFactory");
13:         env.put(Context.PROVIDER_URL, "t3://localhost:7001");
14:         // Now it's time to connect to the EJB Server
15:         try {
16:             InitialContext      initialContext = new InitialContext(env);
17:             AlarmClockHome   home = (AlarmClockHome)
18:                initialContext.lookup("AlarmClock");
19:
20:             System.out.println("Peforming first insert.");
21:             AlarmClock   alarm1 = (AlarmClock) home.create();
22:             System.out.println("Peforming second insert.");
23:             AlarmClock   alarm2 = (AlarmClock) home.create("03/02/99",
24:                 "WBCN", false);
25: 
26:             System.out.println("Station1 = " + alarm1.getRadioStation());
27:             System.out.println("Time1 = " + alarm1.getAlarmTime());
28:             if (alarm1.isFmSet())
29:                 System.out.println("First alarm is FM.");
30:             else
31:                 System.out.println("First alarm is AM.");
32:             System.out.println("Station2 = " + alarm2.getRadioStation());
33:             System.out.println("Time2 = " + alarm2.getAlarmTime());
34:             if (alarm2.isFmSet())
35:                 System.out.println("Second alarm is FM.");
36:             else
37:                 System.out.println("Second alarm is AM.");
38:
39:             System.out.println("Deleting entry");
40:
41:      // Only delete a single entry to see if the data remains in the DB.
42:             home.remove(alarm1.getPrimaryKey());
43:
44:         } catch (Exception e) {
45:             System.out.println(e);
46:         }
47:    }

With an understanding of EJB architecture and client-side use in mind, an example is appropriate.

Note

Note that the code in the following sections depends on the use of a Java Application Server such as BEA Systems WebLogic Server. A Java Application Server provides an execution environment for EJBs to run (live) in. You can download the latest version of WebLogic Server from the BEA Web site at http://www.beasys.com. For your convenience WebLogic Server v4.51 is packaged on the associated CD and runs on Windows 95, 98, NT 4.0, 2000, and various UNIX platforms. See the BEA Web site for more information about WebLogic Server and all it can do.


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.48.135