EJB 3.1 tutorial

EJB 3.1 is now available as early draft and brings lots of interesting improvements, making life lots easier for developers. Let's see five major innovations introduced by EJB 3.1 specifications.

EJB 3.1 tutorial

EJB 3.0 was designed around the concept of ease of development for users. Now designing an EJB application is much easier and less error prone then in the past.

Innovation # 1 No more interfaces are needed!

Until now the Client view of the EJB was a business interface which contained all method exposed to remote clients. Until now middle tier framework like EJB and Spring promoted the idea of interface-based programming which is clearly a useful technique in writing Object Oriented, unit-testable applications.

However, having to replicate the interface methods in the class is often an annoyance; moreover, it takes more time to review your applications because using any IDE you need to climb from the Client view to the EJB interface and then to the implementation class.

So this is a fully EJB 3.1 Session Bean: 
 @Stateless
 public class HelloBean {

  public String doSomething() {
     String message = propertiesBean.getProperty("hello.message");
     return message;
  }

 }
Deploying this EJB will result in the following JNDI binding in the application server:
INFO  [org.jboss.ejb3.nointerface.impl.jndi.AbstractNoInterfaceView
JNDIBinder] Binding the following entry in Global JNDI:

HelloBean/no-interface - EJB3.1 no-interface view
Innovation # 2 Singleton EJBs
Until now, if you wanted to use singleton services in your EJB you had to use some application server specific features. For example, with JBoss AS you can deploy POJO Services and inject them in your application as singleton EJB

See this link for more information about JBoss POJO Services.
If you want something standard across all application servers, then you can use the annotation @Singleton at Class level. Here's an example:
import javax.ejb.Singleton;
import java.util.*;

@Singleton
public class SingletonBean {

 private HashMap cache;

 @PostConstruct
 public void initCache(){
 this.cache = new HashMap();
 }

 public Object get(String key){
 return this.cache.get(key);
 }
 
 public void put(String key,Object value){
 this.cache.put(key, value);
 }
}

Then you can inject the EJB reference in another component like a servlet:
public class MyServlet extends HttpServlet {

 @EJB
 SingletonBean singletonEJB;

 @Override
 public void init(){
 singletonEJB.put("name", "Hello World");
 }

 public void doGet(HttpServletRequest request, HttpServletResponse response)
 throws ServletException, IOException {
 .....
 } 
}
Like all other EJB’s, singletons have all the services such as security, remoting, dependency injection, web services, interceptors and so on.

Another nifty feature in this area is the availability of automatic Singleton inizialization. look at this example
public class MyServlet extends HttpServlet {

 @EJB
 SingletonBean singletonEJB;

 @Override
 public void init(){
 singletonEJB.put("name", "Hello World");
 }

 public void doGet(HttpServletRequest request, HttpServletResponse response)
 throws ServletException, IOException {
 .....
 } 
}
Here the Container is forced to initialize the Singleton (via the @PostConstruct annotation) as soon as the Singleton Bean is deployed. All you have to do is adding the @Startup annotation at class level.

When creating a singleton session bean there are two ways of controlling concurrent access to the singleton's business methods: container-managed concurrency and bean-managed concurrency.

If a singleton uses container-managed concurrency, the EJB container controls client access to the business methods of the singleton. The javax.ejb.Lock annotation and a javax.ejb.LockType type are used to specify the access level of the singleton's business methods or @Timeout methods. Here's an example:
@ConcurrencyManagement(CONTAINER)
@Singleton
public class ExampleSingletonBean {
 private String state;

 @Lock(READ)
 public String getState() {
 return state;
 }

 @Lock(WRITE)
 public void setState(String newState) {
 state = newState;
 }
}
The getState method can be accessed by many clients at the same time, because it is annotated with @Lock(READ). When the setState method is called, however, all the methods in ExampleSingletonBean will be locked to other clients because setState is annotated with @Lock(WRITE). This prevents two clients from attempting to simultaneously change the state variable of ExampleSingletonBean.
Singletons that use bean-managed concurrency allow full concurrent access to all the business and timeout methods in the singleton. The developer of the singleton is responsible for ensuring that the state of the singleton is synchronized across all clients. Developers who create singletons with bean-managed concurrency are allowed to use the Java programming language synchronization primitives like synchronization and volatile to prevent errors during concurrent access.

Innovation # 3
Timer based Services

The timer service of the enterprise bean container enables you to schedule timed notifications for all types of enterprise beans except for stateful session beans. You can schedule a timed notification to occur according to a calendar schedule, at a specific time, after a duration of time, or at timed intervals. The following timeout method uses @Schedule to set a timer that will expire every Sunday at midnight:
@Stateless
public class TimerBean
{
 
@Schedule(dayOfWeek="Sun", hour="0")
 
 public void emitNotification()
 {
 .....
 }
}

The @Schedule annotation supports the following attributes:

Attribute

Allowable Values

Default

Second

[0,59]

0

Minute

[0,59]

0

Hour

[0,23]

0

dayOfMonth

[1,31]

*

Month

[1,12] or {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",

"Oct", "Nov", Dec"}

*

dayOfWeek

[0,7] or {"Sun", "Mon", "Tue",

"Wed", "Thu", "Fri", "Sat"}

*

Year

A four-digit calendar year

*

You can use also cron-style to represent the format of your scheduled task.

Here's a task which is scheduled every 5 minutes:

@Schedule(expression="0 0/5 * * * ?")

Innovation # 4
EJB classes can be now packaged in .WAR files!

The EJB specification states that enterprise beans needs to be packaged in an enterprise module called an xxx.jar. If a Web application needed to use the EJB classes (without replicating the interfaces into the Web Archive) , you had to package the EJB and WEB applications in an xxx.ear archive.This packaging approach is further complicated by the special handling required for any classes or resources that must be shared between the modules.

The EJB 3.1 specification addresses this problem by removing the restriction that enterprise bean classes must be packaged in an ejb-jar file. You now have the option of placing EJB classes directly in the .war file, using the same packaging guidelines that apply to web application classes.

This means that you can place EJB classes under the WEB-INF/classes directory or in a .jar file within the WEB-INF/lib directory. The EJB deployment descriptor is also optional. If it's needed, you can package it as a WEB-INF/ejb-jar.xml file.
WebApp3.1.war
¦   index.jsp
¦
+---META-INF
¦       MANIFEST.MF
¦
+---WEB-INF
    ¦   web.xml
    ¦
    +---classes
    ¦   +---com
    ¦      +---sample
    ¦              MyEJB.class
    ¦              MyServlet.class   
    +---lib
            additionallibs.jar
Innovation # 5
Asynchronous EJB

EJB specification allow the use of asynchronous actions since the release 2.0, when Message Driven Bean (MDB) have been released. Even if MDB are not at all difficult to use, you still need to configure JMS for the purpose of dispatching messages.
In case you don't need JMS in your application, now you can use the @Asynchronous annotation to state that an EJB returns immediately from the invocation.
@Stateless
public class AsynchBean  {
 ...

 @Asynchronous
  public void fireAction(Customer c) {
    try {

      sendInvoice(c);
      sendEmail(c);
   }
    catch (Exception be) {        exc.printStackTrace();     }   } }
EJB 3.1 on JBoss
In order to run EJB 3.1 examples on JBoss download the latest 6.x version of the application server from the JBoss site.

{fcomment}



Advertisement