How Do I Use an EJB?

Given that EJBs are middle-tier business components, they are of little use without a client to drive them. As mentioned earlier, those clients can be Web components, standalone Java clients, or other EJBs.

Regardless of the type of client, using an EJB requires the same set of steps—namely, discovery, retrieval, use, and disposal. Listing 4.7 shows a simple client for use with the Agency EJB illustrating these steps. The following three sections cover these steps in more detail.

Listing 4.7. Simple Agency Client SimpleClient.java
package client;

import agency.*;
import javax.ejb.*;
import javax.naming.*;
import java.rmi.*;
import javax.rmi.*;
import java.util.*;

public class SimpleClient
{
    private static String agencyJNDI = "java:comp/env/ejb/Agency";

    public static void main(String[] args) {
        if (args.length == 1)
            agencyJNDI = args[0];
        else if (args.length > 1) {
            System.err.println("Usage: SimpleClient [ AgencyJNDI ]");
            System.exit(1);
        }

        try {
            InitialContext ic = new InitialContext();
            Object lookup = ic.lookup(agencyJNDI);

            AgencyHome home = (AgencyHome)
                PortableRemoteObject.narrow(lookup, AgencyHome.class);
            Agency agency = home.create();
            System.out.println("Welcome to: "+agency.getAgencyName());
            System.out.println("Customer list: "+agency.getAgencyName());
            Collection customers = agency.findAllCustomers();
            Iterator it = customers.iterator();
            while (it.hasNext())
            {
                String name = (String)it.next();
                System.out.println(name);
            }
            agency.close();
        }
        catch (NamingException ex) {
             System.err.println(ex);
        }
        catch (ClassCastException ex) {
             System.err.println(ex);
        }
        catch (CreateException ex) {
             System.err.println(ex);
        }
        catch (RemoteException ex) {
             System.err.println(ex);
        }
        catch (RemoveException ex) {
             System.err.println(ex);
        }
    }
}

Discovery

To create or find an EJB, the client must call the appropriate method on the EJB's home interface. Consequently, the first step for the client is to obtain a remote reference to the home interface. The client obtains the reference by accessing the J2EE server's name service using JNDI.

For this simple process to work, the following three actions must have taken place:

  • The developer has defined the EJB reference used in the Java code

  • The Deployer has mapped this reference onto the actual JNDI name of the EJB

  • The EJB container has registered the home interface using the JNDI name specified as part of the platform specific deployment descriptor

As discussed on Day 3, each J2EE component has its own Java Component Environment space and the JNDI name used in the client code will be prefixed with java:comp/env. The object retrieved is a reference to the RMI-IIOP remote stub that must be downcast to the home interface. The following code shows the initial lookup required for the Agency EJB:

try
  {
    InitialContext ic = new InitialContext();
    Object lookup =ic.lookup("java:comp/env/ejb/Agency");
    AgencyHome home =
          (AgencyHome)PortableRemoteObject.narrow(lookup, AgencyHome.class);
    ...
  }
  catch (NamingException ex) { /* Handle it */ }
  catch (ClassCastException ex) { /* Handle it */ }

Now that you have a reference to the home interface, you can create the EJB.

Retrieval and Use

Once you have a reference to the EJB home interface, you can call the create() method you saw defined on the AgencyHome interface. The create() method returns a remote reference to the newly-created EJB. If there are any problems with the EJB creation or the remote connection, a CreateException or RemoteException will be thrown.CreateException is defined in the javax.ejb package, and RemoteException is defined in the java.rmi package, so remember to import these packages in your client class.

Now that you have a reference to an EJB, you can call its business methods as follows:

try
{
  ...
  Agency agency = home.create();
  System.out.println("Welcome to: " + agency.getAgencyName());
  ...
}
catch (RemoteException ex) { /* Handle it */ }
catch (CreateException ex) { /* Handle it */ }

The previous code sample shows the getAgencyName() method being called on the returned Agency reference. Again, whenever you call a remote method that is defined in an EJB remote interface, you must be prepared to handle a RemoteException.

NOTE

You will see later that some Entity beans are found rather than created. In this case, all steps are the same except that the create() method is replaced by the appropriate finder method and find-related exceptions must be handled. You still end up with a remote reference to an EJB. All of this is covered when Entity beans are discussed on Day 6.


Disposing of the EJB

You have now created and used an EJB. What happens now? Well, if you no longer need the EJB, you should get rid of it by calling its remove method, and set its reference to null as follows:

// No longer need the agency EJB instance
agency.remove();
agency = null;

The remove() method can throw RemoveException. After calling remove() you should obviously not call any business methods on the bean as it has been removed from use. Using an EJB after remove() has been called will throw a RemoteException.

NOTE

Normally you would only call the remove() method for Session beans. Entity beans (see Day 5) represent data in a persistent data store, and calling remove() for an Entity bean would typically remove the data from the data store.


If you do not remove a Session EJB after a default period of inactivity (typically 30 minutes), then the EJB container will remove the bean on your behalf. This is an example of the added value provided by the EJB lifecycle. A lazy or novice developer can forget to remove an EJB and the container will still tidy up and release resources: a bit like your mother tidying your bedroom when you were a young child.

Running the Client

To compile and run the client, you will need the following:

  • The J2EE classes.

  • Access to the EJB's home and remote interface classes.

  • RMI stubs for the home and remote interfaces.

  • If the client does not have the JNDI name of the EJB compiled in, you may want to provide this on the command line or through a system property.

NOTE

If your client is a J2EE Web client (such as a servlet or JSP as discussed on Day 12, “Servlets” and Day 13, “JavaServer Pages”), then the client will implicitly have access to the J2EE classes, EJB interfaces, RMI stubs and JNDI name server.


When you deploy the EJB, you can usually ask the container for a client JAR file. This client JAR file will contain all of the classes and interfaces needed to compile the client (as defined in the previous bulleted list). You should add this client JAR file to your CLASSPATH when compiling your client.

Client Applications

Application client programs are simple Java programs with a main() method that run in their own JVM but make use of services provided by the J2EE server. Application clients are usually invoked by a program supplied by the J2EE server vendor. The J2EE RI, for instance, provides a program called appclient for running application clients.

The various J2EE server vendors may handle client applications differently, but the J2EE specification allows for application clients to be packaged into JAR files, together with a deployment descriptor, and deployed to the J2EE server. The J2EE RI uses this approach, and Listing 4.8 shows the application client deployment descriptor file (application-client.xml) for the simple Agency application client shown previously in Listing 4.7.

Listing 4.8. Application Client Deployment Descriptor application-client.xml
<?xml version="1.0" encoding="UTF-8"?>
<application-client version="1.4" xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee
/application-client_1_4.xsd">
  <display-name>SimpleClient</display-name>
  <ejb-ref>
    <ejb-ref-name>ejb/Agency</ejb-ref-name>
    <ejb-ref-type>Session</ejb-ref-type>
    <home>agency.AgencyHome</home>
    <remote>agency.Agency</remote>
  </ejb-ref>
</application-client>

An application client deployment descriptor is used to define J2EE server resources required by the client. In this case, a single EJB reference is needed to define the name of the EJB as used in the code (ejb/Agency) and the type and classes for the EJB.

NOTE

As with all applications bundled into a JAR file, the class containing the main() method entry point is defined by a Main-class entry in the JAR Manifest file.


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

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