In our previous article, we did a tutorial of the Java Enterprise Edition 5 for Enterprise JavaBeans version 3 specification. In this article we will look more in depth in the EJB3 specification focusing on constructing a typical an EJB for solving a realistic problem using EJB 3. We will focus on high-level features and services of EJB 3, including the major actors: the beans and clients. It will be obvious to you that EJB 3 services can be delivered in a straight and easy manner.

Diving into a View of EJBs

In the previous tutorial, we showed the change from EJB2 to EJB 2. The key issues that it addressed in relation to EJB 2. A cumbersome programming model, deployment descriptor overload, and the requirement to use a Java Naming Directory Interface for accessing key resources. EJB3 completely revamped itís programming model. Here are the key changes that have drastically simplified EJBs:

Dependency Injection with EJB3
Almost every nontrivial application is made up of two or more classes that collaborate with each other in order to perform some business logic. The conventional method for doing this was for each object to assume responsibility for obtaining its own references to the objects it collaborates with as well as its dependencies. This leads to tightly coupled code that is difficult to test, difficult to reuse, difficult to understand, and often leads to situations where when you fix one bug, it creates one or more new bugs. This is not to say that coupling is unnecessary certain amount of coupling is necessary as uncoupled code isnít capable of doing anything useful. In order to do anything useful, classes need to know about each other somehow. Coupling is necessary, but must be carefully managed.
Tutorial: In Depth View of EJB Bean for Component Developer Exam-a2-dependencyinjection.jpg
Figure: Dependency Injection

With dependency injection, objects are given their dependencies at creation time. This is done by some other object or container that coordinates each object in the system. The container reads target bean configuration, figures out what beans and resources the target bean needs, and injects them into the bean at runtime. There is no need to write lookup code and it is easy to change the configuration to swap out beans and resources as required. So you declare component dependencies and let the container deal with all the issues of service or resource instantiation, initialization, sequencing, and supplies the service or resource references to the clients as required. The dependencies of an object are injected into the objects that need them rather than expecting the object to create or obtain their dependencies themselves. The benefit of this is that component implementations can easily be swapped out as necessary simply by reconfiguring the application.

Dependencies Accessed using JNDI
For all resources that are outside of the EJB container, the only means of accessing them is via the Java Naming Directory Interface (JNDI). This applies as well to invoking a session bean from a client running outside of an EJB container. JNDI has a set of interfaces containing implementations for Remote Method Invocation (RMI), Lightweight Directory Access Protocol (LDAP), CORBA as well as others. In order to perform a JNDI lookup is to setup the JNDI properties in a java.util.Properties object and then pass this object as an argument to InitialContext. Another means to do this is to setup a jndi.properties file and use the no-arg InitialContext constructor. In this case the application server will access the jndi.properties file at runtime. How this is done is shown in the code below:

Java Code: InitialContext with arguments constructor
Properties env = new Properties(); 
// Set container specific JNDI properties 
InitialContext ctx = new InitialContext(env);

Java Code: InitialContext without arguments constructor
InitialContext ctx = new InitialContext();
Once this is completed, you can access remote EJB or other resources:

Java Code: Dependency Injection using Initial Context
TimeService timeService = (TimeService) ctx.lookup(ďejb30.session.TimeServiceĒ);
Another means of doing this is by using the @Resource annotation. This annotation can be used for doing injection with a wide variety of resources (i.e. environment entries, EJB references, JDBC data source, email, JMS resources, etc). An example of how this is done is shown below:

Java Code: Dependency Injection using @Resource annotation
@Stateless 
public class FXMarketBean implements FXMarket {
   ... 
   @Resource(name="jdbc/fxMarketDB") 
   private javax.sql.DataSource dataSource;
As this is a straightforward JNDI resource, it would be straightforward for the EJB container to inject this into the bean. This is similar to doing the same using a deployment descriptor:


XML Code: Dependency Injection using deployment descriptor
<resource-ref> 
      <res-ref-name>jdbc/fxMarketDB</res-ref-name> 
      <res-type>javax.sql.DataSource</res-type>
</resource-ref>
In both cases, the name parameter of using the @Resource or the res-ref-name in the deployment descriptor, they are translated to a fully qualified JNDI mapping (i.e. java:comp/env/[name]). The container then resolves the JNDI references for the resources and then binds the resource to the environment naming context (i.e. java:comp/env for JNDI) during deployment. The container will throw a runtime exception if it is unable to find the resource. This will leave the bean as unusable.

Annotations with EJB3
With the inception of EJB3, it is now possible to do service configuration using Java metadata annotations. This was a significant change from EJB2 where one was required to use XML deployment descriptors. Annotations simplify the EJB programming model by removing this need for detailed deployment descriptors. It also is an effective delivery mechanism for dependency injection.

Basically, annotations allow you to ďaddĒ additional attributes to a Java class, interface, method, or variable. These attributes can be used in a development environment like Eclipse, with a persistence provider like Hibernate, in the runtime environment like the Java EE container, with the Java compiler, or a deployment tool, .Annotations are used like Java modifiers that can be used by anything handling Java source or byte code. An example of a is shown below:

Java Code: Annotation example for Stateless Local Bean
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
@Stateless 
@LocalBean 
public class ViewMonteCarloBean extends MonteCarloBeanBase
The @Stateless and @LocalBean symbols are annotations. What this tells you is that the ViewMonteCarloBean Java class is a local bean and a stateless session bean. Note that we are able to do this by adding a bit of extra information about the class without needing us to implement an interface, extend a class, or add a member variable or method. As annotations are a special kind of interface, we need to import the relevant packages where they are defined. In this case, the @LocalBean and the @Stateless annotations are defined in the javax.ejb.LocalBean.class and javax.ejb.Stateless files respectively. This is for the benefit of the compiler. The runtime environment decides how to use the annotations; in this case to define the POJO as a local stateless session bean. Note that the annotation facility now makes attribute-oriented programming a core part of the Java language.

Finally it isnít a good idea to mix and match configuration with source code such as annotations. If you did, you would need to change source code each time you made a configuration change for anything from a database connection resource to a deployment environment entry. EJB 3 addresses this situation by allowing you to override annotations via XML deployment descriptors where appropriate. This is because in EJB 3 theyíre designed to harmonious coexist. This is an invaluable feature for enterprise applications that can be deployed to a variety of environments such as for a test and a production server. The best way of mixing and matching annotations and XML metadata is to use annotations for everything excluding environmentĖspecific configurations. This should be left for XML.

In the development of Java EE 5.0, it become clear that there was a need to develop a set of annotations for EJB3 in order to facilitate integration with the web tier. They are applicable across servlets, JSF managed beans as well as application clients. You can find them in the javax.annotation.* package. The list of some of the common metadata annotations is provided below.

Tutorial: In Depth View of EJB Bean for Component Developer Exam-a2-annotationtable.jpg
Table - List of Common Annotations for EJB Beans

Note that common metadata annotations such as @Resource, @EJB, @WebServiceRef, @PersistenceContext, and @PersistenceUnit annotations are primary focused on dependency injection avoiding many of the complexities of doing JNDI lookups.

XML Deployment Descriptors
As we mentioned above, XML deployment descriptor is simply an XML file that holds application configuration information. This deployment descriptor describes its contents and environment. In Java EE5, there are various deployment descriptors for the different deployment units. The examples are the Enterprise Archive (EAR), EJB (ejb-jar) and Web Application Archive (WAR) modules. One of the original problems of deployment descriptors was that they were verbose and difficult to make and understand. Alot of the items included were boilerplate items that could have been added automatically unless someone expressly provided by the developer or deployer.

Now with EJB3 and the advent of annotations, best practices have dictated that for application specific items that they be left to annotations and that we use deployment descriptors for environmental specific items. This doesnít prevent the deployer or developer from overriding configuration of the application, as the deployment descriptor will override the annotation, but it provides for a good separation of concerns.

Now that we have covered key parts of the EJB Model that are common across all EJBs whether they are Session or Message Driven Beans or even Entities. Now letís go through other features and services provided by EJBs where they are differences between the different type of EJBs.
The EJBContext
In order to gain access to key container services such as transaction or security, you will need to do this using the EJBContext. It is possible to use dependency injection in order to obtain a SessionContext. In the case of a session bean, there are a number of methods that are added specific to the session beanís environment. These methods are:
getBusinessObject()
getEJBLocalObject() - For EJB2 Beans
getInvokedBusinessInterface()
getMessageContext

An example of a SessionContext being added is shown below:

Java Code: Obtaining a session context using dependency injection
@Stateless 
public class PlaceBidBean implements PlaceBid {
    @Resource 
    SessionContext context;
    ...
}
For message driven beans, there is a similar object called a MessageDrivenContext. Unlike a SessionContext, there are no methods that have been added to it. Instead it will throw exceptions if getEJBHome, getEJBLocalHome or isCallerInRole are called. This is because since the MDB is running in a messaging environment, there is no point in adding methods on a business interface. The means of injecting a MessageDrivenContext into an MDB is shown below:

Java Code: Obtaining a message driven context using dependency injection
@MessageDriven 
public class OrderBillingMDB {
    @Resource MessageDrivenContext context;
    ...
}
Transaction Management with EJB3
EJBs use the Java Transaction API (JTA) for Transaction management support. The JTA is a high-level API in which the application server provider implementation normally exposes functionality at the distributed transaction manager layer. In fact most EJB developers in general need to know about only one JTA interface: javax.transaction.UserTransaction. The reason for this is that the EJB container handles most of the transaction management details. EJB developer only needs to tell the container where the transaction boundary begins and ends and whether to roll back or commit.

There are two ways of using transactions in EJB:
Container-managed transaction (CMT) - used to is to declaratively manage transactions
Bean-managed transaction (BMT) - requires you to explicitly manage transactions programmatically

Both provide abstractions over JTA. Using CMT you can declaratively manage transactions using either annotations or the deployment descriptor. It is important to note that in this version of EJB, only session beans and MDBs support BMT and CMT. The EJB 3 Java Persistence API is not directly dependent on either CMT or BMT but can transparently plug into any transactional environment while used inside a Java EE container. An example of a CMT transaction is shown below:

Java Code: Annotation a session bean and method for transactions
@Stateless 
@TransactionManagement(TransactionManagementType.CONTAINER) 
public class OrderManagerBean {    

   @Resource    
   private SessionContext context;
   ...
   @TransactionAttribute(TransactionAttributeType.REQUIRED) 
   public void placeFXOrder(FXItem fxItem, Customer customer){
   try { 
   if (!bidsExisting(fxItem)){
      validateCredit(customer); 
      chargeCustomer(customer, fxItem); 
      removeItemFromBidding(fxItem);
   } 
   } catch (CreditValidationException cve) {
      context.setRollbackOnly(); 
   } catch (CreditProcessingException cpe){
      context.setRollbackOnly(); 
   } catch (DatabaseException de) {
      context.setRollbackOnly();
   }
 }
}
First the bean is annotated with the @TransactionManagement that tells the container we are using container managed transactions. We then have a EJB Context which is injected into the bean. For the placeFXOrder we have annotated the method with transaction required attribute which means that a transaction will be started by the container whenever this method is invoked. Note within the method that it is specified to rollback the transaction using the EJBContextís object setRollbackOnly method.

EJB3 Security
The two functions of security is to provide authentication (i.e. the process of verifying oneís identity) and authorization (i.e. the process of determining whether the user has access to a resource or task). Both functions are necessary to provide robust security for your application. Authorization is intimately linked with other concepts of security such as users, groups and roles. Java EE security is based primarily on the Java Authentication and Authorization Service (JAAS) API. It provides a pluggable API that facilitates decoupling between the Java EE application and the actual security service since the application interfaces with the service via JAAS API. The JAAS API then has implementations that allow it to talk to Microsoft Active Directory, Novell Directory, Oracle Internet Directory (OID) or Lightweight Directory Access Protocol (LDAP).
Tutorial: In Depth View of EJB Bean for Component Developer Exam-a2-jaas.jpg
Figure: Architecture of Java Authentication and Authorization Service

JAAS lets both authentication and authorization to be performed at any Java EE tier. Most application are accessible via the web and will share its authentication system across various tiers. Once an individual is properly authenticated, JAAS will provide the system with a valid user principal object which is associated with one or more roles. The javax.security.Principal interface has methods which allows the application to check whether the principal/role is authorized to access a particular secure resource. The Principal can be transparently moved from the web tier to business tier when required.

The configuration of web security is kept in the login-config and security-constraint elements of the web.xml file. Below is a configuration showing how to secure the administrative module.

XML Code: Configuration of authentication and authorization for site
<login-config> 
   <auth-method>BASIC</auth-method> 
   <realm-name>FxMarketRealm</realm-name>
</login-config>

... 
<security-constraint>
   <web-resource-collection> 
      <web-resource-name>
      FXMarket Administrative Component
      </web-resource-name> 
      <url-pattern>/admin/*</url-pattern>
   </web-resource-collection> 
   <auth-constraint>
      <role-name>ACCTMGR</role-name> 
   </auth-constraint>
</security-constraint>
This uses the simplest authentication mechanism, BASIC which uses HTTP header-based authentication scheme. This scheme causes the web browser to gather username/password information using a built-in prompt. The other section concerns the realm (i.e. a container specific abstraction over a JAAS driven authentication system) the container needs to authenticate against. Note that it is specified that all URLS that match the pattern /admin/* need to be secured and that only validated principals with the role ACCTMGR can access these resources. Unless you are interested in using programmatic security, this is the essential pattern that is used for declarative security.

Session Beans
As EJBs have been simplified in EJB3, all session beans are made up the two basic parts of any plain old java object (POJO), an interface and an implementation of the bean. There are many benefits to this such as being able to apply design principles such as use construction rather than inheritance. Other benefits are by having all clients access beans through their interface it drastically simplifies the unit-testing of the business logic provided by the session bean as well as facilitating the use of dependency injection. The interface for the POJO is know as the business interface in EJB lingo and the implementation is called the Bean or Bean implementation.

There are a number of rules that applies to EJB3 beans. I will outline them here:
  • Session Beans must have at least one business interface
  • Session Beans must be concrete (i.e. not defined as final or abstract)
  • Session Beans must have a no-argument constructor
  • Session Beans can subclass another session bean or POJO (benefit of the POJO based EJB model)
  • Session Beans business methods and/or lifecycle callback methods may be defined in either the bean class or in a superclass. Note that you can also do annotation inheritance with limitations on the inheritance of annotations for lifecycle methods and resource injections. They all will be inherited by the bean class.
  • Session Beanís business method must not start with ďejbĒ and must be public. You cannot use final or static in the definition of a business method.
There are differences between the different types of sessions beans that are dependent on whether the session bean has the ability to hold the conversational state of the the instance of the object. For those of you who are not aware the conversational state holds the results of the userís interactions with various resources and objects on the site. In the case of an online store, it would hold your shopping basket or wish list as you navigate around the site and make it available for you when you want to access it or modify it. The two types of session beans that differ in terms of conversational state are: stateless session beans and stateful session beans. I imagine you can guess which one holds conversation state when you use it!

The Lifecycle of EJBs
Across all types of EJBs, there are two events that are consistent across their lifecycles. Those events are creation and destruction. For stateful session beans, there are two other phases that they go through called passivation which is when a stateful session bean is serialized to some form of storage and activation which is when the session bean is uploaded from storage and reactivated. The lifecycle of all beans starts with the instantiation of a session bean:
  1. The client obtains a reference either via dependency injection or from a JNDI lookup.
  2. The container invokes the newInstance method on the bean object which translates to a constructor invocation on the bean implementation class.
  3. For beans using dependency injection, all dependencies are resolved meaning the the relevant resources, beans and environmental components are injected into the new bean instance.
  4. After a period of time of use, when the container determines that the instance of a bean is not needed, that instance is destroyed.
During both the creation and destruction, callbacks are invoked in order to give the bean the opportunity to do things like acquire or release resources it may require or to prepare or cleanup the bean state. In the next sections we drill down into the lifecycle of each type of EJB.

Stateless Session Bean (SLSB) Lifecycle
Lifecycles donít get much simpler than the lifecycle for a stateless session bean. It either doesnít exist or it is ready for use. Formally these states are known as Does Not Exist, which is the initial state of every SLSB and Method-Ready Pool in which itís business method can be invoked. In the Method-Ready Pool state, there is a pool of instantiated stateless session beans that are not being used but ready for use. This is the key difference with Stateful Session Beans that donít define instance pooling. Finally note that a session bean's lifecycle is controlled by the container.
Tutorial: In Depth View of EJB Bean for Component Developer Exam-a2-slsblifecycle.jpg
Figure: Lifecycle of Stateless Session Bean

These are the steps that are performed by container for stateless session beans:
  1. The bean is instantiated
  2. The container injects the beanís SessionContext if required.
  3. The container performs any other dependency injection needed by any of the beanís metadata
  4. The container invokes a PostConstruct callback method if it is present in the stateless session bean. The PostConstruct method can then be used for initializing any resources used by the bean. The PostConstruct method is only called once during the lifecycle of the instance when it transitions from the does-not-exist state to the method-ready pool.
Stateful Session Bean (SSB) Lifecycle
Outside of what was mentioned above about stateful session beans not defining an instance pool, there are other areas in which they differ from stateless session beans. Stateful session bean starts from a does-not-exist state and moves to a method-ready state once a client does a business interface lookup or a dependency injection of a bean. This is initiated by the client and not by the container. Similarly to stateless session beans, once a stateful session bean is in a method-ready state, the business method can be invoked.
Tutorial: In Depth View of EJB Bean for Component Developer Exam-a2-ssblifecycle.jpg
Figure: Lifecycle of a Stateful Session Bean

These are the steps that are performed by container for stateful session beans:
  1. The SSB is instantiated
  2. The EJB container injects the beanís SessionContext if required
  3. The EJB container performs any other dependency injection needed by any other the beanís metadata
  4. The EJB container invokes a PostConstruct callback method if it is present in the bean
The beanís business method can no be invoked by the EJB container. As there could be long wait times between invocations of the SSBís business method due to client wait or other activities, the EJB containerís cache can fill up quickly with idle SSBs. In such cases, the container can swap these beans out from the cache to disk or some other form of storage through serialization of the SSB. This process is known as passivation. The reverse of this process, i.e. deserializing the SSB back from Passive to Method-Ready state in order to invoke itís business method, is called activation. How this is done is always dependent on the container and what algorithm it uses for deciding when to change a SSBís state to Passive. Finally the bean can provide a @PrePassivate and/or @PostActivate callback methods which as the name implies gets called immediately before passivation or just after activation. These are very useful when your session bean is using such resources as the database or JMS and you need to either release or reacquire access to these resources.

Message Driven Bean Lifecycle
Message Driven Beanís Lifecycle parallels the lifecycle of stateless session beans. As both donít need to maintain any state information, they are instantiated when the container is started and then held in a method ready pool. The one difference is that the container may decide at any time to create new instances of MDBs.
Tutorial: In Depth View of EJB Bean for Component Developer Exam-a2-mdblifecycle.jpg
Figure: Lifecycle of a Message Driven Bean

These are the steps that are performed by container for message driven beans:
  1. The Message Driven Bean is instantiated
  2. The EJB container injects the beanís MessageDrivenContext if required
  3. The EJB container performs any other dependency injection needed by any other the beanís metadata
  4. The container invokes a PostConstruct callback method if it is present in the message driven bean. The PostConstruct method can then be used for initializing any resources used by the bean. The PostConstruct method is only called once during the lifecycle of the instance when it transitions from the does-not-exist state to the method-ready pool. The method can have any name but must have no arguments and have void as a return.
Once the message arrives in the JMS queue, the beanís OnMessage callback method is invoked. The EJB container will choose any MDB in the pool to respond to the callback as long as they have the same JMS destination. When the container decides to destroy the MDB, the bean will first call the PreDestroy method if required before it transitions back to the does not exist state.

Local Interfaces
As most invocations of Session Beans are done remotely outside of the EJB container via RMI-IIOP protocol, this has a significant impact on performance since method arguments must be passed by value (i.e. serialized then passed over the network and deserialized). This is often the case even when one session bean is invoking another session bean within the same container. it is for this reason that EJB platform provides the possibility of having a local interface for a session beans. In this case, for method invocations, it is possible to pass method arguments by reference which significantly improves performance. The way this is done is by adding the @Local annotation to the bean interface. So it would look like the following:

Java Code: EJB Bean defined as having a local interface
package com.acme.ejbexamples.session;
import javax.ejb.Local;
import com.acme.ejbexamples.domain.Flight;

@Local
public interface MyFlightService {
    public Flight getFlight();
}
By annotating the interface with @Local, this tells the EJB container that this bean can only be invoked by a local client running in the same container. So the implementation might look something like this.

Java Code: Invocation of a local annotated EJB by a local client
package com.acme.ejbexamples.session;
import java.util.*;
import com.acme.ejbexamples.domain.Flight;

@Stateless
public class MyFlightServiceBean implements MyFlightService {
    public Flight getFlight(){
        return new Flight(ďAir France 1099Ē);
    }
}
Of course this is not very useful but in order to provide a description of how to implement a local interface, it will suffice.

Interceptors
Interceptors come out of the concepts behind Aspect Oriented Programming (AOP). The key idea around AOP is to separate common concerns from business methods. Common concerns that are applicable across all parts of an application can be logging, auditing, transactions, security and performance monitoring. What this technique allows is to encapsulate all methods or classes addressing these concerns in interceptors or aspects. Now in EJB3, it makes strategic use of interceptors whenever a business method is invoked by the EJB container.

This ability of the EJB to apply interceptors to business methods of session and message driven beans allows the developer to customize the behavior of your application. All interceptors use the @AroundInvoke annotation on the methods that it applies. The interceptor can be defined in the bean class or separately in its own class. There is only one interceptor method per class.

Below is an example of how an interceptor can be used to measure execution times for the invocation of a specific method:

Java Code: Modification of session bean with an interceptor
package com.acme.ejbexamples.session; 
import javax.ejb.Stateless; 
import javax.persistence.EntityManager; 
import com.acme.ejbexamples.entity.Currency; 
import javax.persistence.PersistenceContext; 
import javax.interceptor.AroundInvoke; 
import javax.interceptor.InvocationContext;

@Stateless public class ForexServiceBean implements ForexService {
   ...
   @AroundInvoke
   public Object methodStats(InvocationContext invctx) throws Exception {
      String name = invctx.getMethod().getName();
      long startTime = System.nanoTime(); 
      System.out.println("Starting method: " + name); 
      try {
         return invctx.proceed();
      } finally { 
            long elapsedTime =
                  System.nanoTime() - startTime; 
            System.out.println("Finished method: " + name +
            " Method took " + elapsedTime + 
            " nanoseconds to execute");
      }
   }
}
As mentioned above, we have an @AroundInvoke annotation that identifies the methodStats method as an interceptor. Now we can use annotations to specify interceptors (or you can use an XML deployment descriptor). When you create an interceptor method, you can name it as you wish but it must have a return type of Object, throw Exception and have a javax.interceptor.InvocationContext object as a parameter. The InvocationContext interface has a number of methods which provide information regarding the business method being invoked.

Note that we are able to access the name of the method by using:

Java Code: Code for accessing name of method being intercepted
String name = invctx.getMethod().getName();
Thatís because the InvocationContext.getMethod() method returns, the business method invoking the interceptor. You can then use The Method.getName() method to obtain the invoking method name:

The next thing to notice is the use of InvocationContext.proceed() method. The proceed() method will invokes the next interceptor if there is more than one interceptor associated with the current business method. It will chain through the series of interceptors if needed by then calling the next interceptor. Once it reaches the last in the chain or if there is only one interceptor it will invoke the proceed() method. Note that the signature of this method is the following:

Java Code: Signature for proceed() method
public Object proceed() throws Exception
Similar to the use in AOP of @Around advice wraps itself, around the method, the
@AroundInvoke indicates that the intercept wraps itself around the business method. It will execute its own code prior to the proceed() method being executed before invoking the business method and then execute the code in the finally clause after the business method is invoked. You can only use one @AroundInvoke annotation method per bean.
We will look at interceptors more in depth in another article. Finally if you want to use an XML descriptor to apply an interceptor, it would have the following syntax:

XML Code: XML descriptor for applying an interceptor
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                                   http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd"
     version="3.1"> 

<assembly-descriptor>
     <interceptor-binding> 
       <ejb-name>MonteCarloBean</ejb-name> 
       <interceptor-class>com.acme.ejbexamples.business.ForexServiceBean</interceptor-class>
       <method-name>cashAndCarry</method-name> <method-params>
       <method-param>int</method-param> </method-params>
      </interceptor-binding>
   </assembly-descriptor>
</ejb-jar>
The preceding XML is a complete deployment descriptor. The <interceptor-binding> element specifies that we want the ForexServiceBean inceptor is executed when the cashAndCarry method is called in the MonteCarloBean.

Finally there are a number of lifecycle callback methods that are available from an interceptor class. They work in the same manner as the lifecycle callback methods (i.e. @PostConstruct, @PreDestroy, @PrePassivate and @PostActivate annotations) that are described for session beans to receive lifecycle callbacks. They are found in the lifecycle callback interceptors or listeners. As the target bean moves through itís lifecycle, the annotated methods in the interceptor class are triggered. An example is shown below:

Java Code: Injector that intercepts lifecycle callback methods
public class AuctionsResourceLogger { @PostConstruct
   public void initialize (InvocationContext context) { 
      System.out.println ("Allocating resources for bean: "
            + context.getTarget()); 
      context.proceed();
   }

   @PreDestroy 
   public void cleanup (InvocationContext context) {
      System.out.println ("Releasing resources for bean: " 
              + context.getTarget());
      context.proceed();
   }
}
Note that lifecycle interceptor methods cannot throw checked exceptions as there is no client for lifecycle callbacks for the problem to propagate up to. As well, a beanís lifecycle callbacks in the bean can also have one or more interceptors. This is the point of calling InvocationContext.proceed method in lifecycle interceptor methods. It doesnít matter whether the interceptor class is applied with or without lifecycle callbacks. The bean lifecycle method or invocation chain will be triggered nonetheless. As I mentioned before these callbacks are often used for acquiring and releasing resources used by the beans. In any case they are extremely useful for numerous reasons.

Interceptor Lifecycle
The lifecycles of interceptor classes is the same as the EJBs they intercept. Refer to Figures 2-4 to see the lifecycles for the different types of EJBs. The interceptors are created, destroyed, passivated and activated alongside the bean instances. You can consider them as an extension of the EJBís bean instance. They also have the same restrictions as the beans to which they are attached. So you can only inject an extended persistence context into a stateful session bean. You could not inject an extended persistence context into a stateless session bean or message driven bean.

The interceptor can also hold internal state since they like the beans to which they are attached have lifecycles and can hook into lifecycle events. This can be used to obtain a resource such as a database, message systems or another remote system as well as close the connection to that resource. Another thing that can be done is to maintain the state that is specific to the bean instance of which the interceptor is attached. This can be useful if you need to do a special cleanup after the bean instance is destroyed.

Exception Handling with Interceptors
Interceptors have very simple exception handling which involves putting a try->catch->finally block around the InvocationContet.proceed() method. In this way, it is possible to abort any invocation before it reaches the target beanís method by throwing an exception within the @AroundInvoke or callback method, catch it and either rethrow a new exception that can be handled as it propagates up to the client or suppressing the exception. Another possibility is to retry the beanís method call after catching an exception from the previous call of the beanís method.

Custom Injection Using JNDI
Sometimes it could be useful to intercept an EJB Callback for when you want to create and define a custom injection annotation. For example, there are some application servers that like to use JNDI as a global registry for configuration or for .NET or other services. In this case, you can define your own annotation for providing this functionality and use an interceptor in order to implement it. An example of how to do this is provided below.

Java Code: Annotation for defining custom injection of JNDI
package com.acme.ejbexamples.annotations; 
import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.FIELD}) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface JndiInjected {
    String value();
}
You would provide the global JDNI names as the value of the value() attribute of the @com.acme.ejbexamples.annotation.JndiInjected annotation. The custom annotation is then used in the following manner:

Java Code: Example of using custom injection of JNDI
@Stateless
public class CustomSessionBean implements CustomSession {
   @JndiInject(ďjava:/TransactionManagerĒ)
   private javax.transaction.TransactionManager tm;

...
}
In this case we are doing global transactions and need a reference to a Java EE JTA Transaction Manager service. In general these are referenced from the global JNDI of the application server provider. In this situation, we can use this custom annotation to pull a reference from from the global JNDI for a field in the session bean. This is shown below using an interceptor class:

Java Code: Custom JNDI Injector
import java.lang.reflect.*; 
import com.titan.annotations.JndiInjected; 
import javax.ejb.*; 
import javax.naming.*; 
import javax.interceptor.*; 
import javax.annotation.*;

public class JndiInjector 
{
   @PostConstruct 
   public void jndiInject(InvocationContext invocation) {
      Object target = invocation.getTarget( ); 
      Field[] fields = target.getClass().getDeclaredFields( ); 
      Method[] methods = target.getClass().getDeclaredMethods( );

      // find all @JndiInjected fields/methods and set them
      try { 
         InitialContext ctx = new InitialContext( ); 
         for (Method method : methods) {
         JndiInjected inject = method.getAnnotation(JndiInjected.class); 
         if (inject != null) {
            Object obj = ctx.lookup(inject.value( )); 
            method.setAccessible(true); 
            method.invoke(target, obj);
         }
         for (Field field : fields) {
              JndiInjected inject = field.getAnnotation(JndiInjected.class);
              if (inject != null) {
                 Object obj = ctx.lookup(inject.value());
                 field.setAccessible(true); 
                 field.set(target, obj);
              }
           }
           invocation.proceed( ); 
} catch (Exception ex) {
   throw new EJBException (ďFailed to execute @JndiInjectedĒ, ex);
   }
  }
}
So the javax.annotation.PostConstruct is now annotated to JndiInject() method and is able to inform the EJB container that the EJB callback is going to be intercepted by the JndiInjector interceptor. The method uses reflection to find the the method and fields that annotated with @JndiInjected, it looks up the referenced JNDI name, and initializes the field or method of the target bean instance. Note that this is done in a try catch sequence since you cannot throw a checked exception but must be wrapped into an EJBException. It is now ready to apply this interceptor across all EJBs.

EJB Timer Service
In order to meet the requirements of modern enterprises, it is necessary for EJB Containers to provide EJBs with scheduling capability. This is known as the EJB Timer Service and is one of the container managed services that must be provided by any JEE 5 certified container. The EJB timer service uses the concept of time-delayed callbacks. The timer is actually a javax.ejb.Timer object that notifies the container of a timed event to be scheduled. What this means is that the service allows you to specify a method (i.e the timeout method) which is invoked automatically after a specified interval of time. The scheduling capability is separated between the EJBs that initiates (via a callback) the scheduler and the EJB method which encapsulate the business process that must run at that specific time. As this implementation of the EJB Timer is standardized across all EBJ Containers, your use of this service will work across all EJB containers.
Tutorial: In Depth View of EJB Bean for Component Developer Exam-a2-timerservice.jpg
Figure: Object Interaction of EJB Timer Service

You can only use either stateless session beans or message driven beans with the EJB timer service. This is because the timer is intimately tied into the EJB container. Therefore EJB entities which are not container managed would not be able to use the EJB Timer Service. The way to use a timer is to have an EJB method register a time-driven callback with the EJB container timer service. On the expiration of the time interval, the timeout method will be invoked. This is shown below.

Java Code: Example of Timer Service use
public class FXMarketBean implements FXMarket {
....
    private void AddNewMarket(String userId, String mkt) {
        try {
            ....
            TimerService timerService = sc.getTimerService();

            // Create a single event timer that expires after twelve hours.
            timerService.createTimer(43200000, mkt);
            System.out.println("Mkt timer created.");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    .....
    @Timeout
    public void updateMktValue(Timer timer) {
        System.out.println("Updating portfolio value of Market: " 
                                    + timer.getInfo());

        // Implement your business logic here to update market value for 
                                    fx positions
        return;
    }
}
We first access the timer service via the EJB context, and then the EJB creates a timer by invoking the TimerService.createTimer() method. The same EJB has a @Timeout annotated callback method, updateMktValue() that is invoked by the container when the scheduled event occurs. In the example, this method containing business process logic would update the positions of the portfolio of FX positions.

The timer interface
A Timer is simply a Java EE representation of a scheduled task. If you want to register timer, it is necessary to the TimerService interface in order to accomplish it. The EJB timer service either made available to the EJB Bean via an injection using the @Resource annotation or through the EJB context. Below is a specification of the options available for using the TimerService interface:
Tutorial: In Depth View of EJB Bean for Component Developer Exam-a2-timerservicetable.jpg
Table: Timer Service Interface

Since the EJB container will pass back the Timer instance that triggered the timeout, you can use this to access information about the object that prompted this timeout or other useful information. The Timer interface provides a number of useful methods for doing this. Below is the list of methods and their descriptions.
Tutorial: In Depth View of EJB Bean for Component Developer Exam-a2-timeinterfaceetable.jpg
Table: Timer Interface

EJB 3.0 / EJB 2.x interoperability
There will be times where you are required to access business functionality running on a legacy EJB 2 application. There are also times where rather than doing a complete upgrade to an existing EJB2 system, your manager decides that they want to modify the EJB2 system to access some new EJB3 based functionality. It is for that reason that the EJB3 specification requires that all compliant containers support EJB2. This will come as a relief to many business that are worried about upgrading their EJB based systems. Below we will show how interoperability between EJB2 and EJB3 functions.

Invoking EJB 2 from EJB 3
It is possible to invoke EJB 2 session or entity beans from EJB 3 session beans or MDBs. A very straightforward method of doing this is via dependency injection. An example of how to do this is shown in the example below where the EJB 2 bean (ChargeCredit) used for credit card transactions is accessed. You must simply use the @EJB annotation to inject an instance of a home object for ChargeCredit into an EJB 3 POJO:

Java Code: Example of invocation of EJB2 Bean within EJB3 Bean
@Stateful public FXOrderBean implements PlaceOrder { 
.. 
@EJB 
public ChargeCreditHome creditHome; 
.. 
void chargeCreditCard(){ 
... 
ChargeCredit chargeCredit = creditHome.create(); 
String confirmationNo = chargeCredit.add(billingInfo, amount);
..
 }
You might remember in EJB 2, an EJB had both remote and home interfaces. In the case of the ChargeCreditEJB, we have ChargeCredit and ChargeCreditHome respectively. In this example we use the create method to get a reference to the remote interface, and then invoke the add business method on the bean. Here we have shown that EJB3 supports EJB 2 quite easily.

If you are interested in invoking an EJB 2 CMP entity bean from EJB 3, it too follows a similar straightforward approach as above. Assume that FXMarket used EJB 2 CMP entity beans for its persistence tier. In this case, we will use the PlaceBid EJB to persists the Bid bean:

Java Code: Example of invoking EJB2 CMP entity bean within EJB3 Bean
@Stateless public PlaceBidBean implements PlaceBid {
... @EJB 
public BidLocalHome bidLocalHome;
 ... 
BidLocal bidLocal = bidLocalHome.create(BidDTO); 
...
}
We create the bean instance (BidDTO) by using a data transfer object (DTO). DTO is used to transfer business object state across the application tiers. Note that creating an entity bean instance will cause the container to persist the bean instance in the database.

Invoking EJB3 from EJB2

If you want to use EJB3 session beans and entities from an EJB2 applications there are some hoops you need to jump through but it is possible. First, you need to remember that in order to access resources as well as your EJBs, you need to use classical JNDI lookups. Also you must declare in your ejb-jar.xml file, your EJB3 session bean. This is to establish a reference to the bean. It would look as follows:

You can use either a container-managed or an application-managed EntityManager in your EJB 2 beans. Assume that ActionBazaar migrated only the persistence tier to JPA and we reverse the context of the EJB Beans such that the PlaceBid EJB is a EJB2 session bean and the CheckCredit is a EJB 3 session bean. To use the container-managed EntityManager from an EJB 2 bean, youíd define the ejb-ref or ejb-local-ref for the EJB 2 bean as follows:

XML Code: EJB2 Deployment Descriptor for EJB3 ejb-local-ref
<session> 
   <ejb-name>PlaceBidBean</ejb-name> 
   <home>fxmarket.buslogic.PlaceBidHome</home>
   <remote>fxmarket.buslogic.PlaceBid</remote> 
   <ejb-class>fxmarket.buslogic.PlaceBidBean</ejb-class> 
   <session-type>stateless</session-type> 
   ... 
   <ejb-local-ref>
      <ejb-ref-name>ejb/CheckCredit</ejb-ref-name> 
      <ejb-ref-type>Session</ejb-ref-type> 
      <local>oldfxmarket.buslogic.CheckCredit</local> 
      <ejb-link>oldfxmarket-ejb.jar#CheckCreditBean</ejb-link>
   </ejb-local-ref> 
</session>
The difference between this deployment descriptor and a standard one is the lack of a local-home element in the ejb-local-ref since EJB3 session beans donít require a home interface. You use JNDI for lookup as the beans using ref-name as shown below:

Java Code: Lookup for EJB3 Bean in EJB2 Session Bean
public class PlaceBidBean implements SessionBean { 
   //EJB 2 bean 
   ...
   public void addBid(Bidder user, double amount) { 
      CheckCredit checkCredit = (CheckCredit)
         context.lookup("java:comp/env/ejb/CheckCredit"); 
            checkCredit.addBid(user, amount);    
    }
   @Stateless 
   public class CheckCreditBean implements CheckCredit{
      //EJB 3 bean
   }
To use an entity with your EJB2 beans, you use either the container managed or application managed EntityManager from the EJB2 bean in the following manner:

XML Code: Deployment descriptor for definition of persistence-context-ref
<session> 
   <ejb-name>PlaceBidBean</ejb-name>
    ... 
   <persistence-context-ref>
      <persistence-context-ref-name> 
      FXMarketEntityManager
      </persistence-context-ref-name>
      <persistence-unit-name>fxMarket</persistence-unit-name> 
   </persistence-context-ref>
</session>
Then, you look up an instance of a container-managed EntityManager via
JNDI:

Java Code: Lookup for EJB3 Entity Manager
Context context = new InitialContext(); 
EntityManager entityManager = (EntityManager)
context.lookup("java:comp/env/ActionBazaarEntityManager"); 
...
entityManager.persist(bid);
Note that the key thing to do is to package a persistence.xml that describes the persistence unit and set version="3.0" in the ejb-jar.xml. So outside of making modifications to the deployment descriptors and using JNDI to get object references it is not complicated to use EJB 3 beans or entities from EJB 2.

OK. Thatís it. In our next article we will continue our review of all things one is required to know for the component developer exam.