Enterprise JavaBeans in a Nutshell
Compiled by Channu Kambalyal
PREFACE
There are few good books available in market that give good
description of EJB along with examples. The EJB specifications are also
available on the web for the public. The short notes prepared here out
of all these resources. These notes form as a quick reference for new
EJB developers. For more details and sample codes refer to the references
given below and also the EJB products' guides.
INTRODUCTION
-
Enterprise JavaBeans (EJB) is the standard specification for the server
side component architecture.
-
EJB enables and simplifies process of building distributed object applications
in Java.
-
EJB is an integral part of Sun's Java 2 Platform, Enterprise Edition (J2EE),
a collection of enterprise technologies.
JavaBeans vs. Enterprise JavaBeans
-
JavaBeans are small grained application bits, used to assemble larger grained
components or applications.
-
JavaBeans are development components and not deployable components, and
do not need a runtime environment.
-
Enterprise JavaBeans standard defines a component architecture for deployable
components.
-
Enterprise JavaBeans are larger, coarser grained application components
that are ready to be deployed in a container that provides runtime services.
Applets/Servlets vs. Enterprise JavaBeans
-
Applets are deployable in a web page, where in the browsers applet viewer
provides the runtime container, Servlets are deployable in a web server
where in a servlet engine provides a runtime container for servlets.
-
Enterprise JavaBeans are deployed in an application server, where in the
application server provides a runtime container.
-
Applets are portable Java programs, Servlets are networked components used
to extend the functionality of a web server. They are well suited to handle
client side operations.
-
Enterprise JavaBeans are intended to perform server side operations.
J2EE TECHNOLOGIES
-
Enterprise JavaBeans (EJB) - Defines how the server side components
are written and is considered the corner stone of Java 2 Enterprise Edition.
-
Java Remote Method Invocation (RMI) and RMI-IIOP - RMI allows for
inter process communication and provides other communication related services.
RMI-IIOP is a portable extension of RMI that can use the Internet Inter-ORB
Protocol (IIOP) and can be used for CORBA integration.
-
Java Naming and Directory Interface (JNDI) - Identifies the locations
of components or other resources across network. JNDI provides for standard
interface for locating users, machines, networks, objects and services.
-
Java Database Connectivity (JDBC) - Relational database bridge that
allows for relatively portable database operations.
-
Java Transaction API (JTA) and Java Transaction Service (JTS) -
Allow for components to provide reliable transaction support.
-
Java Messaging Service (JMS) - Allows for asynchronous distributed
object communications.
-
Java Servlets and Java Server Pages (JSPs) - Servlets and JSPs are
networked components ideally suited for request/responce oriented computing
interacting with clients over HTTP.
-
Java IDL - Java based implementation of CORBA. Allows for integration
with other languages.
-
Java Mail - Allows to send email messages in platform independent,
protocol independent manner from Java programs. Depends on JavaBeans Activation
Framework (JAF).
-
Connectors - Used to connect with mainframe systems running high-end
transactions and Enterprise Resource Planning (ERP) systems.
-
The Extensible Markup Language (XML) - A structured document format
standard that businesses use to exchange business data. EJB and JSP depend
on XML as a meta-markup language for describing content.
ENTERPRISE JAVABEANS OVERVIEW
-
EJB takes a devide-and-conquer approach to server side computing.
-
EJB standard allows for collaboration of six (6) parties.
-
Bean Provider - Provides reusable business components.
-
Container Provider - Supplies low-level runtime execution environment
to run EJB applications.
-
Server Provider - Supplies application logic to contain, manage
and deploy components.
-
Application Assembler - Overall application architect providing
a workflow solution.
-
Deployer - Deploys the chosen components in one or more application
servers.
-
System Administrator - Oversees the well-being of a deployed system.
TYPES OF ENTERPRISE JAVABEANS
-
EJB Specification 1.0 and 1.1 define two different kinds of enterprise
beans: Session Bean and Entity Bean.
-
Session Bean -Session Beans are business objects implementing business
logic, rules and workflow. Usable by one client at a time in contrast to
entity beans whose state is shared among many clients. EJB Container (
not the client) manages the lifetime of the session beans including intantiation,
communication and destruction of the beans. EJB Container pools Session
Beans and reuse for multiple clients. EJB provides for following two (2)
types Session Beans:
-
Stateless Session Bean - used to service single requests. No state
is maintained between requests and is not aware of client history.
-
Stateful Session Bean - can service multiple methods requests or
transactions. Retains the state of the session bean during method invocations.
-
Entity Bean - A component that represents persistent data objects
like customer, order, product, account, etc., allowing transformation of
database's data into Java Objects. Do not contain business logic but implement
data access logic layer. Have life cycle longer than a client's session
and used by multiple clients. EJB provides for following two (2) types
of entity beans:
-
Bean Managed Persistent Entity Bean - Persisted by the component
developer written code that translate in-memory fields into an underlying
data store using API such as JDBC or SQL/J.
-
Container Managed Persistent Entity Bean - Persisted automatically
by the EJB Container. EJB Container use the bean descriptors described
by the developer to map database's objects to in-memory fields of entity
bean.
EJB CONTAINER/SERVER
The EJB Container/Server is responsible for managing the Enterprise
JavaBeans. The container interacts with beans using the bean's required
management call-back methods. These methods are invoked only by the Container
and not the client applications that use them. The Container alerts the
beans about middleware events, makes them available for clients to invoke
remotely, perform transaction co-ordination, manage bean's life cycle and
other tasks. Overview of the features of Container are as follows:
-
Resource and Bean Life Cycle Management - Beans are dynamically
intantiation, reused as appropriate (i.e., re-assigned from client to client
- also called instance pooling) and destroyed.
-
State Management - Containers manage the state by serializing the
bean's conversational state and re-assign it to different client and when
the original client makes the request the state of the bean is again restored.
-
Transactions - Handle the underlying transaction operations, co-ordinate
between the transaction participants.
-
Security - Security is provided using Access Control Lists.
-
Persistence - As per EJB 1.1 containers should manage the persistence
for beans.
-
Remote Accessibility and Location Transparency - Using RMI interfaces,
the client code needs no hard coding of the physical location of the component
it is calling.
ENTERPRISE JAVA BEAN
-
The Enterprise Bean Class - This is the most basic interface that
all bean classes must implement. This interface extents Serializable, thus
making all beans convertible to bit blob. The interface is as follows:
public interface javax.ejb.EnterpriseBean extends java.io.Serializable
{
// No methods or data members
}
-
The EJB Object - This is a proxy object for the enterprise bean
that knows about the networking, security and acts as a glue between the
client and the bean. It exposes every business method that bean itself
exposes and the clients actually communicate with the bean through EJB
object. The EJB products provide the tools to generate the code for the
EJB Object for each bean.
public interface javax.ejb.EJBObject extends java.rmi.Remote
{
public abstract javax.ejb.EJBHome
getEJBHome() throws java.rmi.RemoteException;
// getPrimaryKey() is used only by Entity Beans to find an existing
entity bean in storage.
public abstract java.lang.Object
getPrimaryKey() throws java.rmi.RemoteException;
public abstract void
remove()
throws java.rmi.RemoteException,
javax.ejb.RemoveException;
public abstract javax.ejb.EJBHandle getHandle()
throws java.rmi.RemoteException;
public abstract boolean
isIdentical()
throws java.rmi.RemoteException;
}
Note: You should code an interface that extends EJBObject
interface and include all the required business logic public methods.
-
The Home Object - The Home Object creates EJB Object, finds existing
EJB Object and removes EJB Object. They also contain container-specific
logic, such as load-balancing logic and administrative logic. These are
auto generated by the vendor. This is the implementation of the Home Interface.
-
The Home Interface - You define methods for creating, destroying
and finding EJB Objects. The containers Home Object implements the Home
Interface. EJB defines some required methods that all interfaces must support
and as follows:
public interface
javax.ejb.EJBHome extends java.rmi.Remote
{
public abstract EJBMetaObject getEJBMetaData()
throws java.rmi.RemoteException;
public abstract void
remove(Handle handle)
throws javax.ejb.RemoteException,
java.rmi.RemoveException;
public abstract void
remove(Object primaryKey) throws javax.ejb.RemoteException,
java.rmi.RemoveException;
}
-
Deployment Descriptors - Enable EJB Containers to provide implicit
middleware services to Enterprise Bean Components. These are declared in
a descriptor file (see examples below). The middleware services may include
life-cycle management, persistence, transaction control, and security services.
Session Bean Vs. Entity Bean
-
Session Bean represent business processes, Entity Bean embody permanent
business entities.
-
Session Beans perform business logic, which may use Entity Bean to manipulate
data they represent.
SESSION BEAN
Session Bean represent work performed for a client and represent business
processes involving logic, algorithms, or workflow. Session Beans are
relatively short-lived component. The Container is empowered
to destroy session beans if clients time out. Session beans are in memory
objects and do not survive application server crashes. Session Bean may
perform database operations but the Session Bean itself is not a persistent
object.
Conversational vs. Non conversational Beans - Conversation means
conversation between a client and a bean. The conversation may be over
a single method or multiple methods. A Stateless Session bean is one that
holds conversation over one method call. No state information is stored
between method calls. A Stateful Session Bean is one that holds conversation
over more than one method call and stores the state of the of that conversation
for that client.
All Session Beans' Methods are Serialized: The container guarantees
that no other clients are using that instance. The container automatically
makes the clients to line up one by one to use a bean instance. However
this is in no way a performance bottleneck as container can provide other
instances of the bean to service multiple simultaneous clients.
Because client requests are serialized, you do not need to code your beans
as re-entrant (thread-safe).
A Session Bean should implement the Interface SessionBean shown
below:
public interface javax.ejb.SessionBean
implements javax.ejb.EnterpriseBean
{
public abstract
void getSessionContext(SessionContext ctx)
throws
ava.rmi.RemoteException;
public abstract
void ejbPassivate() throws
java.rmi.RemoteException;
public abstract
void ejbActivate()
throws java.rmi.RemoteException;
public abstract
void ejbRemove()
throws java.rmi.RemoteException;
}
EJBContext: EJBContext is used in determining information about
EJBean's current status at runtime. Information may be about HomeObject
or EJBObject, transactions, security and environment properties. The SessionContext
used in a Session Bean and the EntityContext used in Entity Bean extend
the Interface EJBContext:
public interface javax.ejb.EJBContext
{
public javax.ejb.EJBHome
getEJBHome();
public javax.util.Properties
getEnvironment();
public javax.security.Identity
getCallerIdentity();
public boolean
iscallerInRole(javax.security.Identity);
public javax.jts.UserTransaction
getUserTransaction();
public void
setRollerbackOnly();
public boolean
getRolebackOnly();
}
SessionContext: A SessionContext is a beans gateway to interact
with container. Your bean can query the container to get information about
the current transactional state and current security state.
public interface javax.ejb.SessionContext extends javax.ejb.EJBContext
{
public javax.ejb.EJBObject
getEJBObject();
}
-
Writing Session Beans: -
-
Write a class (say class MySessionBean) that implements interface SessionBean.
You may add the required business logic methods into this class.
-
Write an interface (say interface Count) that extends EJBObject. Include
all public business logic methods.
-
Write an interface (say interface CountHome) that extends EJBHome. Include
required create() methods whose signatures match the ejbCreate() methods
of its SessionBean implementation (i.e., class CountBean).
-
Calling Session Beans:
-
Typical steps include:
-
Look up a home object
-
Use the home object to create an EJB object
-
Call methods on the EJB object
-
Remove the EJB object.
-
Sample Code:
// Get an InitialContext
String url = "t3://localhost:7001";
Context ctx = null;
Properties h = new Properties();
h.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
h.put(Context.PROVIDER_URL, url);
String user = "";
String password = "";
// h.put(Context.SECURITY_PRINCIPAL, user);
// h.put(Context.SECURITY_CREDENTIALS, password);
ctx = new InitialContext(h);
// Obtain HomeObject
Object sessionHomeObject = ctx.lookup("crd_midas_fe.MidasSessionHome");
sessionHome = (MidasSessionHome) PortableRemoteObject.narrow(sessionHomeObject,
MidasSessionHome.class);
// Obtain EJBObject
midasSession = (MidasSession) PortableRemoteObject.narrow(sessionHome.create(),
MidasSession.class);
// Invoke Method of the Session Bean. These workflow steps invoke entity
beans.
midasSession.acceptOffer();
midasSession.getAccountDisclosure();
midasSession.getAccountNumber();
STATELESS SESSION BEAN
-
Characterstics of Stateless Session Bean
-
No Conversational State
-
Only One way to Initialize Stateless Sessions i.e. uses only ejbCreate()
with no parameters.
-
Containers Can Pool and Reuse Stateless Sessions
-
Decoupled from EJB Objects. i.e., reassigned at any time to another EJB
Object.
-
Writing Stateless Session Bean
STATEFUL SESSION BEAN
-
Characteristics of Stateful Session Bean
-
Effect of Pooling achieved using Activation and Passivation and Least
Recently Used Passivation strategy. An exception to this rule is:
any
bean is involved in a transaction cannot be passivated until the transaction
is complete.
-
Conversational State - Follow the rules laid out by Java Object Serialization.
-
Activation/Passivation Call-backs: ejbPassivate() is a warning to the bean
that its conversational state is about to be swapped out. This method ejbPassivate()
may be used to relinquish held resources which may be database connections,
open sockets, open files, etc.,. The exact opposite process occurs during
the activation process.
-
Writing Stateful Session Bean
-
Which to Choose - Stateful or Stateless Session Bean
-
With stateless beans, EJB container is able to pool easily, but the stateful
beans will need to use passivation/activation mechanism to achieve the
same.
-
You need to be extra careful to account for the stateful bean's failure
of loosing the conversations if the EJB product does not provide stateful
recovery.
-
Drawback of the stateless bean: (TBD)
OTHER FUNCTIONALITIES IN SESSION BEAN
-
Using EJB Contexts -
-
Using SessionContext -
-
EJB Security -
ENTITY BEAN
-
Entity Beans are persistent objects that can be stored in a permanent
storage. (Entity Beans were optional part of EJB 1.0).
-
The entity bean is an in-memory Java representation of persistent data.
-
The entity bean data (or data instance) is the physical set of data, such
as a bank account, stored in the database.
-
Files that make up an EntityBean component are: EntityBean class, beans
remote interface which the clients invoke. The vendor provides the tools
to implement this remote interface.
-
The entity bean's Primary Key Class is a unique identifier for the
entity bean. The primary key object must be serializable. The primary key
class may contain any number of attributes or an entire object.
-
Entity Beans are long-lived and may last for about days, months or years.
-
The data transfer is accomplished by the container with two special
methods called ejbLoad() and ejbStore().
-
The ejbLoad() reads data from the persistent storage into the bean's in-memory
fields.
-
The ejbStore() saves the bean instance's current fields into the data storage.
-
You don't have to worry about synchronizing your objects with the underlying
database. This is the one of the advantages of EJB.
-
Several entity beans may represent same underlying data.
-
All entity beans must implement the javax.ejb.EntityBean interface.
-
Interface javax.ejb.EntityBean:
public interface javax.ejb.EntityBean implements
javax.ejb.EnterpriseBean
{
public
abstract void setEntityContext(EntityContext
ctx);
public
abstract void unsetEntityContext();
public
abstract void ejbActivate();
public
abstract void ejbPassivate();
// This is optional in
Entity Beans. Used only to initialize certain initialization parameters.
public
abstract PrimaryKeyClass ejbCreate(<..>);
public
abstract void ejbPostCreate(<..>);
public
abstract void ejbRemove();
// load and store
methods are called only by the container to sync Entity Bean data with
Database
public abstract void
ejbLoad();
public abstract void
ejbStore();
public abstract
void ejbFindByPrimaryKey(<..>);
}
-
Interface javax.ejb.EntityContext:
public interface javax.ejb.EntityContext implements javax.ejb.EJBContext
{
public abstract javax.ejb.EJBObject
getEJBObject();
public abstract java.lang.Object
getPrimaryKey();
}
BEAN MANAGED PERSISTENT ENTITY BEAN
-
In the Bean Managed Persistence Entity Bean, you must define atleast one
finder method - ejbFindByPrimaryKey().
-
It may be necessary to have Entity Context as an instance of the bean to
obtain the context information.
-
Example of ejb-jar.xml file used to configure an Entity Bean:
<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise
JavaBeans 1.1//EN' 'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'>
<ejb-jar>
<enterprise-beans>
<entity>
<ejb-name>midas_beanManaged</ejb-name>
<home>crd_midas_fe.LookupApplicationHome</home>
<remote>crd_midas_fe.LookupApplication</remote>
<ejb-class>crd_midas_fe.LookupApplicationBean</ejb-class>
<persistence-type>Bean</persistence-type>
<prim-key-class>java.lang.String</prim-key-class>
<reentrant>False</reentrant>
<resource-ref>
<res-ref-name>jdbc/midasPool</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</entity>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>midas_beanManaged</ejb-name>
<method-intf>Remote</method-intf>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
<?xml version="1.0"?>
<!DOCTYPE weblogic-ejb-jar PUBLIC '-//BEA Systems, Inc.//DTD WebLogic
5.1.0 EJB//EN' 'http://www.bea.com/servers/wls510/dtd/weblogic-ejb-jar.dtd'>
-
A WebLogic-ejb-jar.xml file used to configure a Bean Managed Persistent
Entity Bean in Weblogic Server 5.1:
<weblogic-ejb-jar>
<weblogic-enterprise-bean>
<ejb-name>midas_beanManaged</ejb-name>
<caching-descriptor>
<max-beans-in-cache>100</max-beans-in-cache>
</caching-descriptor>
<reference-descriptor>
<resource-description>
<res-ref-name>jdbc/midasPool</res-ref-name>
<jndi-name> weblogic.jdbc.jts.midasPool</jndi-name>
</resource-description>
</reference-descriptor>
<jndi-name>crd_midas_fe.LookupApplicationHome</jndi-name>
</weblogic-enterprise-bean>
</weblogic-ejb-jar>
CONTAINER MANAGED PERSISTENT ENTITY BEAN
-
With Container managed Persistence Entity Beans, you do not implement any
persistence logic in the bean itself. The Container implicitly performs
all the database operations.
-
The access modifier of the Container Managed Fields of the Bean
should be ste as public to allow for the container to access the
fields.
-
All Container Managed Fields must be Serializable.
-
Rule for Serialzation: A. All primitive types are automatically serialized.
B. Object marked as transient are not serialized. C. Any object
not marked transient must implement java.lang.Serializable.
-
For container-managed persistence, ejbCreate() returns a null, unlike the
case of bean-managed persistence, where it returns a primary key. (Note:
The method ejbCreate() is still declared ro return a Primary Key, even
when it actually returns a null. See 9.4.2 of the EJB 1.1 specification).
-
No finder methods are required to be implemented they are implemented by
the container.
TRANSACTIONS IN EJB
-
Transactions are at the very core of EJB. (For the basics of Transactions,
ACID properties please refer to Transactions topics in TUXEDO on this site).
Among different types of transactions namely Flat Transactions, Nested
Transactions, Chained Transactions, EJB supports only one flavour of Transactions
- Flat Transactions. There are 2 ways to Demarcate Transactional Boundaries
namely - Programmatically or Declaratively.
-
EJB allows you to specify how the bean may be enrolled in a transaction
by setting Transaction Attributes as follows:
-
Transaction Attribute Values:
-
TX_BEAN_MANAGED - Used for programmatically controlling the transactions.
-
TX_NOT_SUPPORTED - Used when the bean need not be involved in a
transaction at all.
-
TX_REQUIRED - Used when the bean should always run in a Transaction.
-
TX_REQUIRES_NEW -Use when the bean always requires a new transaction.
If there is already a transaction underway when the bean is called, that
transaction is suspended during bean invocation and a new transaction launched.
-
TX_SUPPORTS - Used when the bean requires to be in a transaction
only if the client had one running already. If the call is not under transaction,
the bean runs with no transaction at all.
-
TX_MANDATORY - Used when a transaction must be already running when
the bean method is called. If transaction is not already running, the javax.ejb.TransactionRequired
exception is thrown back to the caller. In this case, the bean relies on
the third party to start the transaction before the bean is called. The
container will not automatically start a transaction.
-
Transactional Isolation ("I" in ACID): There are 4 transactional
isolation levels in EJB:
-
TRANSACTION_READ_UNCOMMITTED - Does not offer any isolation
guarantees but offers high performance. This is the weakest isolation level.
Advantage is that the locks are not required.
-
TRANSACTION_READ_COMMITTED - Solves the dirty read problem (i.e.,
reading data from a database that has not been committed). This is the
default isolation level for most databases like Oracle or Microsoft SQL
Server.
-
TRANSACTION_REPEATABLE_READ - Solves the dirty read problem as well
as unrepeatable read problem (i.e., Data in the database is changed
after reading the committed data. This occurs when no locks are used to
lock out those other transactions from modifying the data).
-
TRANSACTION_SERIALIZABLE - Solves dirty read, unrepeatable
read and also the phantom problem (Phantom problem occurs when
a new phantom record appears that wasn't there before). This is the strictest
isolation level and enforces the isolation ACID property to the fullest.
PROGRAMMATIC TRANSACTIONS
-
When using programmatic Transactions, you are responsible for issuing a
begin
statement
and either a commit or an abort statement.
-
A programmatic bean should be deployed with TX_BEAN_MANAGED transaction
attribute.
-
Example:
public void deposit(double
amt) throws AccountException
{
javax.transaction.UserTransaction userTran = ctx.getUserTransaction();
userTran.begin();
balance += amt;
try {
userTran.commit();
}
catch(Exception e) {
throw new AccountException("Deposit failed due to " + e.toString());
}
}
DECLARATIVE TRANSACTIONS
-
Using Declarative Transactions, you allow for the components to be automatically
be enlisted in transactions.
-
A bean using the Declarative(or Container Managed) Transactions should
be deployed with TX_REQUIRED, TX_MANDATORY, or TX_REQUIRES_NEW
transaction
attribute.
-
-
Example:
public interface
javax.ejb.SessionSynchronization
{
public void afterBegin();
public void beforeCompletion();
public void afterCompletion(boolean);
}
The session that is required
to be in transaction should impement the interface javax.ejb.SessionSynchronization
as follows:
public class MySessionBean
implements SessionBean, SessionSynchronization
{
private SessionContext ctx;
public int
val;
public void ejbCreate(int val) throws createException { this.val
= val; }
public int getVal() { return ++val; }
public void ejbRemove() { }
public void ejbActivate() { }
public void ejbPassivate() { }
public void setSessionContext(SessionContext ctx) { }
public void afterBegin() {
System.out.println("Transaction Begun!");
}
public void beforeCompletion() {
System.out.println("Transaction is about to be completed (with Commit or
Abort)!");
}
public void afterCompletion(boolean b) {
if(b == true) {
System.out.println("Transaction Committed!");
}
if(b == false) {
System.out.println("Transaction Aborted!");
--val;
}
}
}
CORBA AND RMI-IIOP
REFERENCES
-
Enterprise JavaBeans Specification, v1.1, Final Release, Sun Microsystems
Inc.Dec. 17, 1999
-
Mastering Enterprise JavaBeans and Java 2 Platform, Enterprise Edition,
Ed Roman, Wiley Computer Publishing Company, 1999