Skip Headers

Oracle9iAS Migrating From WebSphere
Release 9.0.2

Part Number A95110-01
Go To Documentation Library
Home
Go To Table Of Contents
Contents
Go To Index
Index

Go to previous page Go to next page

5
Migrating Enterprise Java Beans

This chapter provides you with an overview of Sun Microsystems' Enterprise JavaBeans (EJB) architecture and its implementation in Oracle9iAS. In addition, the issues involved in migrating EJB components from WebSphere Advanced Edition to Oracle9iAS are presented.

This chapter contains these topics:

Overview of Enterprise JavaBeans

Enterprise JavaBeans (EJB) is the standard server-side component architecture for developing and deploying object-oriented Java applications. It enables developers to quickly and easily build distributed applications.

A major goal of the EJB architecture is to provide component portability at both the source code level and the binary code level.

EJB components, called enterprise beans, are server-side components, written in Java, that typically contain the business logic of an application. The different types of enterprise beans are summarized in Table 5-1.

Table 5-1 Types of EJBs
Type of Enterprise Bean Description

Session bean

A component created to provide a service on behalf of a single client; it lives only for the duration of a single client/server session.

Entity bean

A component representing data maintained in a data store; it can persist as long as the data it represents.

Although the EJB architecture does provide for component portability, certain implementation-specific aspects of an EJB component remain non-portable. These include:

EJB Migration Considerations

One of the goals of the EJB initiative is to deliver component portability between different environments not only at source-code level, but also at a binary level, to ensure portability of compiled, packaged components. While it is true that EJB does offer an appreciable deal of portability, there are still a number of non-portable, implementation-specific aspects that need to be addressed when migrating components from one application server to another. Typically, an EJB component requires low-level interfaces with the container in the form of stubs and skeleton classes that will probably always need to be container implementation-specific. In effect, a clear partitioning between portable and non-portable elements of an EJB component can be drawn from the EJB 1.1 specification:

The following sections describe EJB specifications, session beans, and entity beans, transactions and concurrency, the WebSphere support for these APIs and WebSphere extensions, the difference between OC4J and WebSphere in the EJB containers and finally the migration path to OC4J.

EJB Functionality and Components

In brief, the goal of EJB technology surpasses the basic Java object model by integrating new functionality important for enterprise systems:

From a developer's point of view, an EJB is presented as a group of files that brings together:

The EJB Server

EJB servers manage low-level system resources, allocating resources to the containers as they are needed. The EJB Server hosts and provides a runtime environment for the EJB containers. Containers are transparent to the client--there is no client API to manipulate the container, and there is no way for a client to tell in which container an enterprise bean is deployed. However, the EJB container and the EJB servers are not clearly separated constructs. The EJB specification only defines a bean-container contract and does not define a container-server contract.

EJB container

The EJB container is a specialized service in which enterprise beans are deployed. EJB containers insulate the deployed enterprise beans from the underlying EJB server and provide a standard application programming interface (API) between the beans and the container. This specialized service manages their life cycle, transactions, security, naming, persistence, and so on, according to a specific contract and constrained model delineated by the EJB specification. To do this, the container uses the generic services provided by the server.

EJB Specification Roles

The Enterprise JavaBeans specification identifies the following roles that are associated with a specific task in the development of distributed applications.

Enterprise Bean Provider

Typically an expert in the application domain; for example, in the financial or telecommunications industry. The bean provider implements the business task without being concerned about the distribution, transaction, security, and other non-business aspects of the application.

Application Assembler

This is also a domain expert. The application assembler composes an application from various prefabricated building blocks (that is, enterprise beans) and adds other components such as GUI clients, applets, and servlets to complete the application. While composing an application, an assembler is only concerned with the interfaces to enterprise beans, but not with their implementation.

Deployer

The deployer is specialized in the installation of applications. The deployer adapts an application, composed of a number of enterprise beans, to a target operation environment by modifying the properties of the enterprise beans. The deployer's tasks include, for example, the setting of transaction and security policies, specifying JNDI names by setting the appropriate properties in the deployment descriptor, and integration with enterprise management software.

EJB Server Provider

Typically a vendor with expertise in distributed infrastructures and services. The server provider implements a platform, which facilitates the development of distributed applications and provides a runtime environment for them. This role can also provide specialized containers that wrap a certain class of legacy applications or systems.

EJB Container Provider

An expert in distributed systems, transactions, and security. A container is a runtime system for one or multiple enterprise beans. It provides the glue between enterprise beans and the EJB server. A container can be both, prefabricated code as well as a tool that generates code specific for a particular enterprise bean. A container also provides tools for the deployment of an enterprise bean and hooks into the application for monitoring and management.

System Administrator

The system administrator is concerned with a deployed application. The administrator monitors the running application and takes appropriate action in the case of abnormal behavior of the application. The administrator ensures that the hardware and network hosting the application is maintained and serviceable for the duration of the application's availibility. Typically, an administrator uses enterprise management tools that are connected to the application by the deployer through the hooks provided by the container.

Session Beans

A session bean is an object that executes on behalf of a single client. The container creates the session bean instance in response to a remote task request from a client. A session bean has one client; in a sense, a session bean represents its client in the EJB server. Session beans can also be transaction-aware--they can update shared data in an underlying database but they do not directly represent the shared database data. The life of a session bean is transient and relatively short-lived. Typically, the session bean lives for as long as its client maintains the session "conversation." When the client terminates, the session bean is no longer associated to that client. A session bean is considered transient because the session bean instance is removed should the container crash, and the client must reestablish a new session object to continue.

There are two types of session beans: Stateful Session Beans (SFSB) and Stateless Session Beans (SLSB). Both of these beans must implement javax.ejb.SessionBean. However their life cycles are different within a EJB container.

Stateful Session Beans

A session bean typically maintains the state of the interaction or conversation with its client--that is, the session bean holds information about the client across method invocations and for the duration of the client session. A session bean that maintains its state is called a stateful session bean. When the client ends its interaction with the session bean, the session ends and the bean no longer maintains the state values.

The Life Cycle of Stateful Session Beans

A session bean's life cycle begins when a client invokes a create() method defined in the bean's home interface. In response to this method invocation, the container does the following:

  1. Creates a new memory object for the session bean instance.

  2. Invokes the session bean's setSessionContext() method. This method passes the session bean instance a reference to a session context interface that can be used by the instance to obtain container services and get information about the caller of a client-invoked method.

  3. Invokes the session bean's ejbCreate() method corresponding to the create() method called by the EJB client.

Ready State

After a session bean instance is created, it moves to the ready state of its lifecycle. In this state, EJB clients can invoke the bean's business methods defined in the remote interface. The actions of the container in this state are determined by whether a method is invoked transactionally or non-transactionally:

Transactional Method Invocations

When a client invokes a transactional business method, the session bean instance is associated with a transaction. After a bean instance is associated with a transaction, it remains associated until that transaction completes. Furthermore, an error results if an EJB client attempts to invoke another method on the same bean instance and invoking that method causes the container to associate the bean instance with another transaction or with no transaction. The container then invokes the following methods:

  1. The afterBegin() method if the session bean implements the SessionSynchronization interface.

  2. The business method in the bean class that corresponds to the business method defined in the bean's remote interface and called by the EJB client.

  3. The bean instance's beforeCompletion() method, if the session bean implements the SessionSynchronization interface.

The transaction service then attempts to commit the transaction, resulting either in a commit or a roll back. When the transaction completes, the container invokes the bean's afterCompletion() method (if the bean implements the SessionSynchronization interface), passing the completion status of the transaction (either commit or rollback) to the afterCompletion() method.

If a rollback occurs, a stateful session bean can roll back its conversational state to the values contained in the bean instance prior to beginning the transaction. Stateless session beans do not maintain a conversational state, so they do not need to be concerned about rollbacks.

Non-transactional Method Invocations

When a client invokes a nontransactional business method, the container simply invokes the corresponding method in the bean class.

Pooled State

The container has a sophisticated algorithm for managing which enterprise bean instances are retained in memory. When a container determines that a stateful session bean instance is no longer required in memory, it invokes the bean instance's ejbPassivate() method and moves the bean instance into a reserve pool. A stateful session bean instance cannot be passivated (deactivated) when it is associated with a transaction.

If a client invokes a method on a passivated instance of a stateful session bean, the container activates the instance by restoring the instance's state and then invoking the bean instance's ejbActivate() method. When this method returns, the bean instance is again in the ready state.

Because every stateless session bean instance of a particular type is the same as every other instance of that type, stateless session bean instances are not passivated or activated. These instances exist in a ready state at all times until their removal.

Removal

The lifecycle of a stateful session bean ends when an enterprise bean client or the container calls a remove() method defined in the bean's home interface or remote interface. In response to this method invocation, the container calls the bean instance's ejbRemove() method. The container can end stateless session beans by this method, or it can pool them for later use.

A container can implicitly call a remove method on an instance after the lifetime of the EJB object has expired. The lifetime of a session EJB object is set in the deployment descriptor with the timeout attribute.

Stateless Session Beans

A session bean may also be a stateless session bean. A stateless session bean does not maintain information or state for its client. A client may invoke a method of a stateless session bean to accomplish some objective, but the bean will hold values in its instance variables only for the duration of the method call. The stateless session bean does not retain these values (or state) when the method completes. Thus, all instances of stateless session beans are identical except when they are in the midst of a method invocation. As a result, stateless session beans can support multiple clients. The container can maintain a pool of stateless bean instances, and it can assign any instance to any client.

The Life Cycle of a Stateless Session Bean

The stateless session bean's life cycle has two states:

When a bean instance is in the does-not-exist state, this means that it has not yet been instantiated. When a bean instance is instantiated by the container and is ready to serve client requests, it is in the method-ready pool state. The container moves a stateless session bean from the does-not-exist state to the method-ready pool state by performing the following three operations:

  1. Invoke the Class.newInstance() method on the stateless bean class.

  2. Invoke the
    SessionBean.setSessionContext(SessionContext context) method on the bean instance.

  3. ejbCreate() method is invoked on the bean instance.

Entity Beans

An entity bean represents an object view of persistent data maintained in a domain model, as well as methods that act on that data. To be more specific, an entity bean maps to a record in your domain model. In a relational database context, one bean exists for each row in a table. A primary key identifies each entity bean. Entity beans are created by using an object factory create() method. Access to entity beans may be shared by more than one client--multiple clients can simultaneously access an entity bean. Entities access and update the underlying data within the context of a transaction so that data integrity is maintained. Entity beans are also implicitly persistent as an EJB object can manage its own persistence or delegate its persistence to its container. Based on the type of persistence in entity beans are divided into two types:

Container-managed Persistence (CMP) Entity Beans

Container Managed Persistence (CMP) allows developers to build EJB components without having to directly deal with persistence during development. For CMP Entity Beans, the EJB container is responsible for persisting the state of the entity beans and synchronization of instance fields within the persistence store (the database). This means that the container would, for example, manage both generating and executing SQL code to read and write to the database. Because it is container-managed, the implementation is independent of the data source. All container-managed fields need to be specified in the deployment descriptor for the persistence to be automatically handled by the container. CMP Entity Beans are wrappers for persistent data--commonly in the form of relational database tables--with additional support for transaction control and security.

Bean-managed Persistence (BMP) Entity Beans

For BMP Entity Beans, the entity bean is directly responsible for persisting its own state and the container does not need to generate any database calls. Each BMP EJB is responsible for storing and retrieving its own state from a backing store in response to specific "hook" messages (like ejbLoad() and ejbStore()) that are sent to it at appropriate times during its lifecycle. Consequently, this implementation is less adaptable than the previous one as the persistence needs to be hard-coded into the bean.

The Entity Beans Life Cycle

An entity bean is considered to be long-lived and its state is persistent. It lives as long as the data remains in the database, rather than for the life of the application or server process. An entity bean survives the crash of the EJB container. Once an enterprise bean is deployed into a container, clients can create and use instances of that bean as required. Within the container, instances of an enterprise bean go through a defined life cycle. The events in an enterprise bean's life cycle are derived from actions initiated by either the client or the container. The life cycle of entity beans has three states:

Does-not-exist State

At this stage, no instances of the bean exist. An entity bean instance's life cycle begins when the container creates that instance. After creating a new entity bean instance, the container invokes the instance's setEntityContext() method. This method passes to the bean instance a reference to an entity context interface that can be used by the instance to obtain container services and to retrieve information about the caller of the client-invoked method.

Pooled State

Once an entity bean instance is created, it is placed in a pool of available instances of the specified entity bean class. While the instance is in this pool, it is not associated with a specific EJBObject. Every instance of the same enterprise bean class in this pool is identical. While an instance is in this pooled state, the container can use it to invoke any of the bean's finder methods.

Ready State

When a client needs to work with a specific entity bean instance, the container picks an instance from the pool and associates it with the EJBObject initialized by the client. An entity bean instance is moved from the pooled to the ready state if there are no available instances in the ready state.

There are two events that cause an entity bean instance to be moved from the pooled state to the ready state:

When an enterprise bean instance is in the ready state, the container can invoke the instance's ejbLoad() and ejbStore() methods to synchronize the data in the instance with the corresponding data in the data source. In addition, the client can invoke the bean instance's business methods when the instance is in this state. All interactions required to handle an entity bean instance's business methods in the appropriate transactional (or non-transactional) manner are handled by the container, unless the EJB developer wrote the bean to handle these interactions itself. When a container determines that an entity bean instance in the ready state is no longer required, it moves the instance to the pooled state. This transition to the pooled state results from either of the following events:

The state that an entity bean represents is shared and transactional. In contrast, if a session bean has state, it must be private and conversational.

Object-relational (O-R) Mapping and Persistence

The problem of persistence is complex, and many research projects are being carried out on this subject. One of the important points to remember is that at runtime, objects (as it happens, EJBs) are not isolated entities but referenced mutually. Therefore, the problem of persistence does not concern isolated objects, but complex object graphs. There are many questions to answer. How can an object graph in memory be projected on a disk and vice versa? How can synchronization problems between the graph on disk and the graph in memory be resolved? How do you go about loading in memory only the parts of the graph being used at a given moment? How can the graph be saved in a relational database (object-relational mapping technologies)?

The EJB specification attempts to render container-managed persistence with a clean separation between an entity bean and its persistent representation. That is, a separation between the data logic methods (such as the logic in an entity bean to add two fields together) and JDBC. The reason this separation is valuable is that the persistent representation of an entity bean (such as changing from a relational database to an object database) can be modified without affecting the entity bean logic.

To achieve this clean separation, container-managed persistent entity bean classes must be written to be devoid of any JDBC or other persistence logic. The container then generates the JDBC by subclassing your entity bean class. The generated subclass inherits from your entity bean class. Thus, all container-managed persistent entity beans are each broken up into two classes: the superclass (which the user writes, and contains the entity bean data logic) and the subclass (which the container generates, and contains the persistence logic). With these two classes, a clean separation of entity bean logic and persistent representation is achieved. The actual entity bean is a combination of the superclass and the subclass.

EJB Transactions and Concurrency

A transaction is a set of statements that must be processed as a single unit. Transactions must have four properties recalled with the acronym ACID: Atomicity, Consistency, Isolation and Durability.

The EJB specification describes the creation of applications that enforce transactional consistency on the data manipulated by the enterprise beans. However, unlike other specifications that support distributed transactions, the EJB specification does not require enterprise bean and EJB client developers to write any special code to use transactions. Instead, the container manages transactions based on two deployment descriptor attributes associated with the EJB module and the enterprise bean. EJB application developers are freed to deal with the business logic of their applications.

A J2EE 1.2 compliant EJB container should support flat transactions, the most common kind of transctions. A flat transaction cannot have any child (nested) transactions. These are the only transaction types supported by EJBs.

The Java Transaction API(JTA)

The JTA APIs specifies start and end transactions.

interface javax.transaction.UserTransaction
{
  public abstract void begin();
  public abstract void commit();
  public abstract void rollback();
  public abstract void setRollbackOnly();
  public abstract int getStatus();
  public abstract void setTransactionTimeout(int);
}

interface javax.transaction.Status
{
  public static final int STATUS_ACTIVE;
  public static final int STATUS_MARKED_ROLLBACK;
  public static final int STATUS_PREPARED;
  public static final int STATUS_COMMITTED;
  public static final int STATUS_ROLLEDBACK;
  public static final int STATUS_UNKNOWN;
  public static final int STATUS_NO_TRANSACTION;
  public static final int STATUS_PREPARING;
  public static final int STATUS_COMMITTING;
  public static final int STATUS_ROLLING_BACK;
}

The JTA UserTransaction interface is actually an interface to the application server's transaction manager. It is the public API exposed by the transaction manager. To get a reference to this, you must look up the interface via JNDI, just like you use JNDI to lookup EJB homes, JDBC drivers, etc. The application server must publish the JTA under "java:comp/UserTransaction".

Context ctx = new InitialContext(...);
  javax.transaction.UserTransaction userTran =
         (javax.transaction.UserTransaction) PortableRemoteObject.narrow(
                           ctx.lookup("javax.transaction.UserTransaction"),
                           javax.transaction.UserTransaction.class);

Transaction Boundaries

Transaction boundaries mark the beginning and end of transactions. The application developer chooses the boundaries. The J2EE specification mentions three ways of controlling transactional boundaries: programmatically inside bean code (bean-managed transactions), programmatically from client code (client-managed transactions), and declaratively inside deployment descriptors (container-managed transactions).

Client-Managed Transactions

A Java client can use the javax.transaction.UserTransaction interface to explicitly demarcate transaction boundaries. The client program obtains the javax.transaction.UserTransaction interface using the JNDI API.The EJB specification does not imply that the javax.transaction.UserTransaction is available to all Java clients. The J2EE specification specifies the client environments in which the javax.transaction.UserTransaction interface is available.

Container-Managed Transactions (CMT)

Whenever a client invokes an enterprise bean, the container interposes on the method invocation. The interposition allows the container to control transaction demarcation declaratively through the transaction attributes set in the deployment descriptor.

For example, if an enterprise bean method is configured with the "Required" transaction attribute, the container behaves as follows: if the client request is not associated with a transaction context, the container automatically initiates a transaction whenever a client invokes an enterprise bean method that requires a transaction context. If the client request contains a transaction context, the container includes the enterprise bean method in the client transaction.

An entity bean must always be designed with container-managed transaction demarcation. For entity beans using container-managed persistence, transaction isolation is managed by the data access classes that are generated by the container provider's tools. The tools must ensure that the management of the isolation levels performed by the data access classes will not result in conflicting isolation level requests for a resource manager within a transaction.

Bean Managed Transactions (BMT)

The enterprise bean with bean-managed transaction demarcation must be a session bean. An instance that starts a transaction must complete the transaction before it starts another new transaction. A session bean can use the EJBContext and the javax.transaction.UserTransaction object to programmatically demarcate transactions. For session beans with bean-managed transaction demarcation, the bean code can specify the desirable isolation level programmatically in the enterprise bean's methods using the resource manager specific API. For example, the bean provider can use the java.sql.Connection.setTransactionIsolation(...) method to set the appropriate isolation level for database access.

For transactions, a session bean can either use container-managed transactions or bean-managed transactions. Entity beans must use container-managed transactions. Whether an enterprise bean uses bean-managed or container-managed transaction demarcation, the burden of implementing transaction management is on the EJB container and server provider.

Transaction Isolation and Concurrency

The transaction isolation attribute tells the container how to limit concurrent reads in a database. The EJB 1.1 specification removed the guidelines for managing transaction isolation levels for beans with container-managed transaction demarcation. But since bean deployers still require mechanisms to govern EJB concurrency, WebSphere continues to support it along with other mechanisms discussed in the next section.

Using CMP, different databases need different SQL statements while trying to acquire a read/write lock at the "database" level as opposed to optimistic/pessimistic concurrency or locking at the container/bean level. For example, MS-SQL Server needs a "SELECT ... AT ISLOLATION SERIALIZABLE", Oracle needs a "SELECT ... FOR UPDATE" as a method of acquiring 'locks' or in other words at a transaction isolation level 'Serializable' to prevent dirty/unrepeatable/phantom reads. Hence, it is difficult to use generic SQL clauses in conjunction with transactions and locks at the database level without resorting to vendor-specific clauses.

The need is for a simple time stamp/versioning mechanism in EJB 1.1 (even EJB 2.0 seems to imply that acquiring a read/write lock at the database level is up to the EJB vendor, which vendors may or may not provide). All that the time stamp and versioning do is compare versions when the client sends data over for modification. The reading could have been done by different clients in different transactions. Hence, if another client tries to update the same data in the entity bean instance, the version numbers will not match if the data has been updated by another client, and an exception can be raised that effectively tells the client to 'refresh' the information, i.e. get the data again to see what might have changed since the client first requested it for modification. This is analogous to performing an "Update <table> set <fields> where <fields = fields_read_at_transaction_start>". The only difference is that the above technique works across transactions, i.e. it prevents a client from overwriting committed changes made by another client.

Session beans that use bean-managed transaction have transaction attributes associated with each method of the bean. The attribute value tells the container how it must manage the transactions that involve this bean. There are six different transaction attributes that can be associated with each method of a bean. This association is done at deployment time by the application assembler or deployer.

EJB supports distributed flat transactions. The distribution mechanism makes it possible to involve bean objects on multiple EJB servers or to update data in multiple databases in a single transaction. Every client method invocation on a bean is supervised by the bean's container, which makes it possible to manage the transactions according to the transaction attributes that are specified in the corresponding bean's deployment descriptor.

A particular transaction attribute can be associated with an entire bean and apply to all its methods or just to an individual method. The scope of a transaction is defined by the transaction context that is shared by the participating bean objects.

EJB Caching

EJB containers allow smart caching of entity beans, which allow some operations to occur in memory rather than at database level. Caching conserves system resources used in making a database connection by eliminating database accesses to unchanged data. There are three caching options available for the container in committing a transaction:

Option A : The container caches a readily available instance between transactions, which has explicit access to the state of the object in the persistent storage. That is, each instance of the EJB will be held in memory. This option is supported by WebSphere and OC4J but should only be used in a single node system. Neither WebSphere nor OC4J enforce this restriction, hence, it is the bean deployer's responsibility to ensure that this restriction is satisfied. This means that the beans using this option will only be used within a single container. It is thus the responsibility of all clients of that bean to always direct their requests to the one bean instance within that specific container.

Option B: The container caches the instance between transactions which does not have access to the persistent object state. This option is not supported by WebSphere nor OC4J.

Option C: The container does not cache the instance between transactions. An entity bean's state is read once per transaction at the beginning of each transaction- even if the value did not change from the last time it was read. The instance is returned to the pool after the transaction is completed. This is the default option supported by WebSphere and OC4J and should be used in multiple node configurations.

Differences between the EJB 1.0 and EJB 1.1 Specifications

This section summarazies differences between versions of the EJB specification.

Changes Specific to Entity Beans

The most obvious change in EJB 1.1 is its mandated support for entity beans which was optional in EJB 1.0 Specification. This support must be complete, embracing support for both container-managed and bean-managed persistent entities. The major changes to entity beans are listed below.

Enterprise JavaBeans 1.1 introduces a new bean-container interface called the environment-naming context (ENC). The ENC is a JNDI name space that is specific to a bean type and its context at runtime. To simplify the bean-container interface, the ENC is made available, by default, when a JNDI context is created. The JNDI ENC enhances the bean-container contract by adding new functionality, but it doesn't completely replace the EJBContext. In EJB 1.1, the JNDI ENC and the EJBContext together represent the complete bean-container interface.

Example 5-1 is an example of an EJB 1.0 bean using the EJBContext to read an environment property used to validate a request (the comparison is applicable to both entity and session beans). Example 5-2 shows an EJB 1.1 bean using the new JNDI ENC to obtain an environment property to validate a request.

Example 5-1 Using the EJBContext

public class AccountBean implements EntityBean
{ 
  int id; 
  double balance; 
  EntityContext ejbContext; 
  public void setEntityContext(EntityContext ctx)
  { 
     ejbContext = ctx; 
  } 
  public void withdraw(Double withdraw)throws WithdrawLimitException
  { 
     Properties props = ejbContext.getEnvironment(); 
     String value = props.getProperty("withdraw_limit"); 
     Double limit = new Double(value) 
     if (withdraw.doubleValue() > limit.doubleValue())
        throw new WithdrawLimitException(limit); 
     else 
        balance = balance - withdraw.doubleValue(); 
  } 
... 
} 

Example 5-2 Using the environment properties in EJB 1.0

public class AccountBean implements EntityBean { 
  int id; 
  double balance; 
  EntityContext ejbContext; 
  public void setEntityContext(EntityContext ctx)
  { 
     ejbContext = ctx; 
  } 
  public void withdraw(Double withdraw) throws WithdrawLimitException
  { 
     InitialContext jndiContext = new InitialContext(); 
     Double limit = (Double) 
                     jndiContext.lookup("java:comp/env/withdraw_limit"); 
     if (withdraw.doubleValue() > limit.doubleValue()) 
                                  throw new WithdrawLimitException(limit); 
     else 
        balance = balance - withdraw.doubleValue(); 
  } 
... 
}

In EJB 1.0, environment properties are limited to String types and are available through the EJBContext. In EJB 1.1, environment properties can be of type String or any one of the primitive numerical wrappers (integer, long, double, boolean, byte, and float); they are available through a default JNDI context. Why the change? EJB 1.1 wanted to extend the bean-container contract to address many of the issues that would have mandated complicated changes to the EJBContext interface. To avoid the limitations of EJBContext -- its definition is fixed and therefore limited -- the JNDI ENC was introduced, which provides a more dynamic and extensible bean-container interface. The EJBContext still exists with some changes, but most of the new EJB 1.1 features are realized through the JNDI ENC.

WebSphere 3.5.x Support for the EJB API

WebSphere supports EJB 1.0 specification with some additional features. WebSphere supports:

WebSphere Advanced Edition 3.5.3 does not support these EJB 1.1 features:

WebSphere and VisualAge for Java extend the EJB specification with the following features:

Read-only Methods

The EJB specification does not provide a standard mechanism to let the container check if the bean's state has changed within a unit of work. The specification assumes that all beans accessed during a transaction are "dirty," and must have their state written back to the persistent store at the end of a transaction. WebSphere provides an extension to the EJB specification with the const method flag in the deployment descriptor of entity beans. It lets the developer tell the container which methods are const or read-only--in other words, it doesn't change the state of the bean. For these methods EJB container does not call ejbLoad at the end of the method call.

EJB Finder-Helper Interface

WebSphere uses a concept called a "FinderHelper" to define the finder logic for CMP entity beans.The following finder logic is required for each finder method (other than the findByPrimaryKey method) contained in the home interface of an entity bean with CMP:

Example 5-3 Finder Helper Interface

    Public interface AccountBeanFinderHelper
    {
      String findLargeAccountsQueryString ="select * from ejb.accountbeantblwhere balance > ?";
    }

This file contains one static java.lang.String field for each finder method declared in the EJB home interface. The strings are initialized with SQL queries executed dynamically when bean instances are retrieved in a finder method. Note that this file is specific to the WebSphere application server.

CMP in WebSphere

The CMP model in WebSphere allows a set of entity EJBs to be read from a relational database in the findXXX() method with only single SQL SELECT call. This is much more efficient then BMP case, which requires N+1 SQL calls to accomplish the same task.

Transactions

WebSphere supports two-phase commits for distributed transactions for Oracle , DB2, and Sybase and MQ Series. Distributed transaction support is also provided for Oracle and Microsoft SQL Server using the Merant drivers in addition to the existing support for DB2 and Sybase. WebSphere 3.5.3 also supports distributed transactions over EJBs and JMS.

WebSphere never passivates an active bean, i.e. a bean participating in a transaction. WebSphere will throw a ROLLBACK exception back to the client.

WebSphere also makes the UserTransaction interface available to Java clients including servlets, JSPs, and standalone programs.

EJB Inheritance

WebSphere provides EJB inheritance similar to Java class inheritance.This EJB inheritance model is specific to the IBM EJB development environment. This is an extension of the EJB specification. In EJB inheritance, an enterprise bean inherits properties, such as CMP fields and association roles, methods, and method-level control descriptor attributes from another enterprise bean that resides in the same EJB group.

Distributed exceptions

Support for chaining distributed exceptions is provided by the com.ibm.websphere.exception Java package. The following classes and interfaces make up this package

Access beans

An access bean adapts an enterprise bean to the JavaBeans programming model by hiding the home and remote interfaces from the access bean user (that is, an EJB client developer). This is specific to IBM WebSphere environment. These access beans are packaged in com.ibm.ivj.ejb.access. There are three types of access beans:

Associations between enterprise beans

WebSphere supports one-to-one and one-to-many associations for CMP beans. The generated code is specific to WebSphere and VisualAge for Java environment specific.

In the EJB 1.1 specification, the application would have been required to throw an EJBException, but this has not yet been implemented in WebSphere Advanced Edition 3.5.3.

Migrating EJB Applications from WebSphere to Oracle9iAS OC4J

There are four aspects of an EJB that differ between WebSphere and Oracle9iAS OC4J:

The following features cannot be migrated to OC4J:

EJB Code Changes

In general, enterprise beans written to version 1.0 of the EJB specification are mostly compatible with version 1.1. However, you need to modify or recompile enterprise bean code in the following cases:

Changes specific to transaction API:

and changing it to:

import javax.transaction.*

This should be changed to the following in OC4J:

initialContext.lookup("java:comp/UserTransaction")

Client Level Code Changes

The following code changes are necessary:

In WebSphere, the initial naming context is obtained by the following code:

java.util.Properties properties =new java.util.Properties();
properties.put(javax.naming.Context.PROVIDER_URL,"iiop:///");
properties.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY,
                           "com.ibm.ejs.ns.jndi.CNInitialContextFactory");
javax.naming.InitialContext initialContext =
                              new javax.naming.InitialContext(properties);
initialContext.lookup("com/ibm/Hello");

The string "///" for the PROVIDER_URL property indicates to the runtime environment to find the naming service at the standard port on the local machine. The general form of the PROVIDER_URL string is "iiop://hostname:port/". The value of the second property, INITIAL_CONTEXT_FACTORY, is the class name of the naming service factory.

To migrate to OC4J, this code must be changed as follows:

Changes in Transactional Semantics

The following should be noted:

Object-relational (O-R) Mapping

With EJBs, O-R mapping is done differently according to the EJB container used (in practice, according to the application server).This means that in order to import an EJB into a different container, it is necessary to go through this development phase again. This is the case with WebSphere and OC4J, since they have different ways of generating O-R mapping classes. WebSphere uses the WebSphere Studio and the VisualAge for Java development environment to generate code for O-R mapping. WebSphere supports one-to-one and one-to-many associations among EJBs.

OC4J supports the EJB 2.0 O-R mapping model. EJB 2.0 is not backward compatible with EJB 1.1, rather, it is a complete break with the old way of doing CMP persistence. OC4J supports one-to-one and one-to-many associations.

Deployment of EJBs

Since WebSphere 3.5.x is at the EJB 1.0 specification level, the EJB JAR files are deployed using serialized deployment descriptors. These cannot be directly deployed on OC4J, which supports the EJB 1.1 XML-based deployment descriptors. Consequently, the EJB JAR files must be re-archived using the EJB 1.1 deployment descriptors. Package individual or multiple EJB components in EJB JAR files and place assembly and deployment properties for EJBs in the standard deployment descriptor XML file (ejb-jar.xml) within the EJB archive file. The deployment descriptor contains attribute and environment settings that define how the container invokes enterprise bean functionality. Every enterprise bean (both session and entity) must have a deployment descriptor that contains settings for the following attributes:

The deployment descriptor for an entity bean must also contain settings for the following attributes. These attributes can be set on the bean only. They cannot be set on a per-method level.

These attributes can be set for the entire enterprise bean or for the individual methods in the bean. The container uses the definition of the bean-level attribute unless a method-level attribute is defined, in which case the latter is used.

<container-transaction>
  <method>
     <ejb-name>LogEntEJB</ejb-name>
     <method-name>*</method-name>
     <trans-attribute>Required</trans-attribute>
  </method>
  <method>
     <ejb-name>EntUtenteEJB</ejb-name>
     <method-name>*</method-name>
     <trans-attribute>Required</trans-attribute>
  </method>
</container-transaction>

OC4J EJB Container Setting

To cache EJB instances, you specify maximum instance limits for each entity bean in orion-ejb-jar.xml with your application and place it in the META_INF directory.

<?xml version="1.0"?>
<orion-ejb-jar>
  <enterprise-beans>
     <entity-deployment name="BeanName" location="BeanName"
           max-instances="5" validity-timeout="3600000"/>
  </enterprise-beans>
</orion-ejb-jar>


Go to previous page Go to next page
Oracle
Copyright © 2002 Oracle Corporation.

All Rights Reserved.
Go To Documentation Library
Home
Go To Table Of Contents
Contents
Go To Index
Index