April 24, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Introduction to EJBs: Part 2

  • July 30, 2002
  • By Sams Publishing
  • Send Email »
  • More Articles »

This is the second of four installments that make up Chapter 4: Introduction to EJBs from the book Sams Teach Yourself J2EE in 21 Days (ISBN:0-672-32384-2) written by Martin Bond, Dan Haywood, Debbie Law, Andy Longshaw, and Peter Roxburgh, published by Sams Publishing.


What's in an EJB?

So far, you have been presented with a "black box" view of an EJB; it provides business functionality via an RMI remote interface, and it cooperates with its container to perform its duties. To understand, use, and ultimately write EJBs, you will need to know more in concrete terms about the Java programming artefacts that make up an EJB. In other words, what's in one?

The Business Interface

The primary purpose of an EJB is to deliver business or application logic. To this end, the bean developer will define or derive the business operations required of the bean and will formalize them in an RMI remote interface. This is referred to as the bean's business or remote interface as opposed to the home interface you will look at in a moment.


Note

You may see references to local EJB interfaces and wonder how these relate to the current discussion. Don't worry about local interfaces for the moment; they are covered on Day 6 when you examine entity EJBs.


The actual methods defined on the remote interface will depend on the purpose of the bean, but there are certain general rules concerning the interface:

  • As with any RMI-based interface, each method must be declared as throwing java.rmi.RemoteException in addition to any business-oriented exceptions. This allows the RMI subsystem to signal network-related errors to the client.

  • RMI rules also apply to parameters and return values, so any types used must either be primitive, Serializable, or Remote.

  • The interface must declare that it extends the javax.ejb.EJBObject interface. This provides a handful of basic methods that you will encounter as you progress.


Caution

Failure to conform to the rules about extending javax.ejb.EJBObject and throwing RemoteException will cause the interface to be rejected by tools that manipulate EJBs. Additionally, if you use parameter or return types that do not conform to the rules, your bean will compile and even deploy, but will fail with runtime errors.


The issue regarding object parameters and return values is worth considering for a moment. When you pass a parameter into a local method call, a reference to the original object is provided to be used within the method. Any changes to the state of the object are seen by all users of that object because they are sharing the same object. Also, there is no need to create a copy of the object—only a reference is passed.

On the other hand, when using RMI remote methods, objects that are serializable (implement the Serializable interface) are passed by value, whereas objects that are remote (that is, EJBs) are passed by reference. Pass by value means that a copy of the object is sent. This has several implications. First, users of a serializable object passed across a remote interface will no longer share the same object. Also, there may now be some performance costs associated with invoking a method through a bean's remote interface. Not only is there the cost of the network call, but also there is the cost of making a copy of the object so that it can be sent across the network. Most of the time, it will be serializable objects that are passed.

You can see an example of an EJB remote interface in Listing 4.1—in this case, the one for the Agency EJB used in the case study.

Listing 4.1 Remote Interface for the Agency EJB

package agency;

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

public interface Agency extends EJBObject
{
  String getAgencyName() throws RemoteException;
	
  Collection findAllApplicants()
   throws RemoteException;
  void createApplicant(String login, String name, String email)
   throws RemoteException, DuplicateException, CreateException;
  void deleteApplicant (String login)
   throws RemoteException, NotFoundException;

  Collection findAllCustomers() throws RemoteException;
  void createCustomer(String login, String name, String email)
   throws RemoteException, DuplicateException, CreateException;
  void deleteCustomer (String login)
   throws RemoteException, NotFoundException;

  Collection getLocations()
   throws RemoteException;
  void addLocation(String name)
   throws RemoteException, DuplicateException;
  void removeLocation(String code)
   throws RemoteException, NotFoundException;

  Collection getSkills()
   throws RemoteException;
  void addSkill(String name)
   throws RemoteException, DuplicateException;
  void removeSkill(String name)
   throws RemoteException, NotFoundException;

  List select(String table)
   throws RemoteException;
}

The interface lives in a package called agency, which will be common to all the classes that comprise the EJB. The definition imports java.rmi.* and javax.ejb.* for RemoteException and EJBObject, respectively. The rest of the interface is much as you would expect from any remote Java interface—in this case, passing Strings and returning serializable Collections.

Notice that all the methods must be declared as throwing RemoteException. This means that the client will have to handle potential exceptions that may arise from the underlying distribution mechanism. However, your application will probably want to employ exceptions itself to indicate application-level errors. These exceptions should be declared as part of the remote interface, as shown by the use of NotFoundException and DuplicateException in the Agency interface.

The Business Logic

After an interface is defined, there is the none-too-trivial task of implementing the business logic behind it. The business logic for an EJB will live in a class referred to as the bean. The bean consists of two parts:

  • The business logic itself, including implementations of the methods defined in the remote interface

  • A set of methods that allow the container to manage the bean's lifecycle.


Note

Although the bean itself must contain these elements, note that it is possible, indeed common, for non-trivial beans to delegate some or all of their business functionality to other, helper, classes.


Drilling down into these areas reveals more about the structure of an EJB.

Implementing the Business Interface

The first thing to note is that the bean itself does not implement the remote interface previously defined. This may seem slightly bizarre at first sight, because the equivalent RMI server would have to implement the associated remote interface. However, there is a very good reason for this.

As you will see later, it is possible to ask the container to apply services, such as access control, on behalf of the EJB simply by setting attributes in the EJB configuration information. To do this, the container must have some way of intercepting the method call from the client. When it receives such a method call, the container can then decide if any extra services need to be applied before forwarding the method call on to the bean itself. Sticking with the security example, the container would examine security information configured for the EJB before deciding whether to forward the method call to the bean or to reject it. The details about access control are covered on Day 15, "Security," but you can see that it is necessary to interpose between the client and the bean to "automagically" deliver such services.

The interception is performed by a server-side object called the EJBObject (not to be confused with the interface of the same name). The EJBObject acts as a server-side proxy for the bean itself, and it is the EJBObject that actually implements the EJB's remote interface. Figure 4.2 shows the relationship between the client, the bean, and the EJBObject.

As shown in Figure 4.2, the client calls the business methods on the EJBObject implementation. The EJBObject applies the required extra services and then forwards the method calls on to the bean itself. The EJBObject is separate from the RMI stub and skeleton that provide the remote procedure call capability.

Figure 4.2: The EJBObject acts as a server-side proxy for the bean itself.

So, your bean must implement the business methods defined in the remote interface. The container uses the method signatures defined in the interface, together with the Java reflection API, to find the appropriate methods on the bean, so you must ensure that you use the correct method signatures. Despite this, the bean should not implement the remote interface itself (the reasons for this are discussed later). However, if you are using a developer tool that supports the creation of EJBs, it will generally generate empty methods for you to populate. Listing 4.2 contains the outlines of the business methods in the example AgencyBean.

Listing 4.2 Business Method Implementation Signatures for the AgencyBean

package agency;

import java.rmi.*;
import java.util.*;
import javax.ejb.*;
// Remaining imports removed for clarity

public class AgencyBean implements SessionBean
{
  public String getAgencyName() {
   // Code removed for clarity
  }

  public Collection findAllApplicants() {
   // Code removed for clarity
  }

  public void createApplicant(String login, String name, String email)
   throws DuplicateException, CreateException {
   // Code removed for clarity
  }


  public void deleteApplicant (String login)
   throws NotFoundException {
   // Code removed for clarity
  }

  public Collection findAllCustomers() {
   // Code removed for clarity
  }

  public void createCustomer(String login, String name, String email)
   throws DuplicateException, CreateException {
   // Code removed for clarity
  }

  public void deleteCustomer (String login) throws NotFoundException {
   // Code removed for clarity
  }

  public Collection getLocations() {
   // Code removed for clarity
  }

  public void addLocation(String name) throws DuplicateException {
   // Code removed for clarity
  }

  public void removeLocation(String code) throws NotFoundException {
   // Code removed for clarity
  }

  public Collection getSkills() {
   // Code removed for clarity
  }

  public void addSkill (String name) throws DuplicateException {
   // Code removed for clarity
  }

  public void removeSkill (String name) throws NotFoundException {
   // Code removed for clarity
  }

  public List select(String table) {
   // Code removed for clarity
  }

   // Remaining methods removed for clarity

}

The detail of the method implementations have been removed for clarity, because the main area of interest here is how the method signatures match up with those on the remote interface. The contents of the methods are largely the creation and dispatch of JDBC statements and handling the results from the queries.

Note that the bean does not implement the Agency interface. You can also see that various of the methods, such as addSkill(), declare that they throw an application-specific exception—in this case, DuplicateException.


Note

Note that your bean methods will only throw business exceptions or standard Java exceptions. They should not throw java.rmi.RemoteException, because such exceptions should only be generated by the RMI subsystem.






Page 1 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel