EJB 3 tutorial for Enterprise developers

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 top picks

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.

#1 Interfaces are not mandatory any more

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;
  }

 }

Please note that Remote Interfaces are still needed for your EJB Remote Clients as you can learn in this article: WildFly remote EJB client tutorial

# 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

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);
 }
}

Next, 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.

You can learn more in detail EJB 3 Singleton in the following article: Singleton EJB tutorial

#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 * * * ?")

You can learn more about EJB Timers in the following article: How to code EJB Timers like a pro

#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


# 5 Asynchronous EJBs


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();     
    }   
  } 
}

Found the article helpful? if so please follow us on Socials