Saturday, January 30, 2010

Wednesday, June 10, 2009

Enterprise JavaBeans 3.0

Hi Friends, In this post, I am going to discuss about Enterprise JavaBeans(EJB) 3.0.

Hope we all worked with EJBs. We know the power of EJB in creating distributed applications, but we should accept the difficulties in creating EJB applications. Don't worry! Here is EJB 3.0 for developing distributed applications with much ease.




Enterprise JavaBeans [Sun Definition]
An Enterprise JavaBeans is a server-side component that encapsulates the business logic of an application. EJB technology enables the development of distributed, transactional, secure and portable applications based on Java technology.

The main goal of EJB is to develop the distributed application with less effort by delegating most of the services such as transaction, security, persistence, concurrency, pooling and much more to server vendors. So developers can focus on business logics rather than concentrating on these services.
Why EJB 3.0?

As discussed above, server vendor provides most of the services for developers. But still developer faces more complexity in understanding and developing enterprise beans.

There are many reasons which states the complexity of EJB 2.x


> Creating several interfaces and implement several unnecessary callback methods.

> The component interfaces require implementation of EJBObject or EJBLocalObject and handling of many unnecessary exceptions.

> Complexity of the EJB deployment descriptors.

> The container-managed persistence, being based on the EJB model, is overly complex to develop and manage. Several basic features are missing--such as a standard way to define a primary key using a database sequence. The EJBQL syntax is very limited.
> EJB components are not truly object-oriented, as they have restrictions for using inheritance and polymorphism.

> Developers cannot test EJB modules outside an EJB container and debugging an EJB inside the container is difficult.

> Looking up and invoking an EJB is a complex task. Detailed knowledge of JNDI is required for even the most basic use of an EJB in your application.


EJB 3.0 focuses on eliminating the above complexities and makes development much simpler.




Working with Enterprise JavaBeans 3.0


EJB 3.0 New Features

POJO and POJI based

JavaBeans and interfaces are often referred to as Plain Old Java Objects (POJOs) and Plain Old Java Interfaces (POJIs), respectively. The EJB class and interface will now resemble POJO and POJI respectively.

The unnecessary requirement of the artifacts like home interface is being removed. You do not have to implement one of the EJB interfaces (SessionBean, EntityBean* or MessageDrivenBean) from javax.ejb package.


* - Entity Beans are removed from EJB 3.0 and the persistence of entity (POJO) is handled through Java Persistence API (JPA). We will discuss this later.

Here comes another question, how does container know which POJO is a managed EJB component? The answer is simple. These informations are now associated with POJOs using annotations.

You can either use Stateless, Stateful, MessageDriven or Entity to annotate the bean class.




POJO with Annotation in EJB 3.0


For example, if we want to define a stateless EJB, we need to define the EJB as follows:

import javax.ejb.Stateless;

@Stateless
public class TestBean implements Test
{
public void display(String value)
{
System.out.println("Value displayed thru' TestBean: " + value);
}
}

The interfaces for EJBs, either remote or local, do not have to implement EJBObject or EJBLocalObject. The bean class now implements the business interface.
In our example TestBean implements Test interface.

import javax.ejb.Remote;

@Remote
public interface Test
{
public void display(String value);
}


Annotations support

EJB 3.0 uses the new feature of J2SE 5.0 called annotation. Using annotation, we can easily embed metadata information to the source code.

In EJB 3.0, annotations replace deployment descriptors. Each attribute in the deployment descriptor has default values so you do not have to specify these attributes unless they want a value other than the default value. These values can be specified using annotations in the bean class itself.

The EJB 3.0 specification also defines a set of metadata annotations such as bean type, type of interfaces, resource references, transaction attributes, security and so on. For example, if you want to define transaction settings for a particular EJB method, you can define the following in the bean class:

@Stateless
public class BankBean implements Bank {
…

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void transfer(long debitAccountId, long creditAccountId, double amount) throws BankException {
…
}
…
}

Callback methods

In EJB 2.x, if you implement SessionBean or MessageDrivenBean interface, you need to implement unnecessary callback methods even though you don’t need it.

But in EJB 3.0, these overhead are completely removed. If you really need the use of callback methods, then you can keep any methods you wish as callback methods. Only thing, we need to do is to annotate the method with corresponding provided annotation.

For example,

@Stateful
public class CartBean implements Bean {

…

@PostConstruct
public void initialize(){
…
}

@PreDestroy
public void reset(){
…
}


}

Listeners

We will discuss this in Persistence Model Post.


Interceptors

The interceptors offer fine-grained control over the method invocation flow. Interceptors are methods that are invoked automatically when the business methods of a bean are invoked. Using interceptors enables a clean distinction between the business logic code and meta or support code.
You can use them on stateless session beans, stateful session beans and message-driven beans. The interceptor may be either a method in the same bean class or an external class.
The @Interceptor or @Interceptors annotation is used to indicate which external classes will be used as interceptors, while the @AroundInvoke annotation is used to identify a method as an interceptor.

Let us see how this is accomplished in the code.

@Stateless
@Interceptor(value=”test.ProfilingInterceptor”)
public class TestBean implements Test {
…
}

public class ProfilingInterceptor {
…
@AroundInvoke
public Object checkPermission(InvocationContext inv) throws Exception {
System.out.println(“checkPermission interceptor invoked.”);
…
}
}


Dependency injection

EJB 3.0 introduces powerful mechanisms for obtaining references to resources and for injecting references to EJB-related objects.
In general, injection is a technique of relying on the container (Java EE application server) to provide reference to objects it has access to.

In the earlier versions of EJB specification, the resources have to be looked up using JNDI. Now with dependency injection all these complex lookups are eliminated.




Lookup Vs Dependency Injection



Below are some common annotations used for injection

@Resource
Used to inject resource reference that the container has access to but is not directly related to EJB. Any resources that are available to Java application server is available for reference using the @Resource annotation. Examples include: javax.sql.DataSource, javax.transaction.UserTransaction, javax.jms.Queue, javax.ejb.SessionContext and much more.

Developers just need to do the following:

@Resource SessionContext context;
@Resource(name=”jdbc/myDataSource”)
DataSource dataSource;

This annotation can also be used with methods as


@Resource
private void setDataSource(DataSource ds) {
dataSource = ds;
}

@EJB
This annotation is used to inject the enterprise bean reference. While instantiating the object, container injects the corresponding enterprise bean reference into the specified attribute.

For ex:

@EJB RegistrationBean registrationBean;

@PersistenceContext
One of the most powerful annotation for dependency injection in EJB 3.0 is @PersistenceContext. This is used to inject the EntityManager object which is used to synchronize entities and the database backing them.
We will discuss more about EntityManager in “Persistence Model” section.

Below is the usage of this annotation

@PersistenceContext EntityManager em;

Message Driven Beans are discussed in a seperate post.

Also, we will discuss Java Persistence API in seperate post.