What is EJB? The evolution of Enterprise JavaBeans

Java's server-side platform for developing distributed business applications

Enterprise JavaBeans (EJB) is a specification for developing large-scale, distributed business applications on the Java platform. EJB 1.0 was released in 1998. The most current release, EJB 3.2.3, has been adopted for inclusion in Jakarta EE, where it will be renamed Jakarta Enterprise Beans.

EJB architecture

The EJB architecture consists of three main components: enterprise beans (EJBs), the EJB container, and the Java application server. EJBs run inside an EJB container, and the EJB container runs inside a Java application server.

There are two types of EJB--session beans and message-driven beans:

  • Session beans are invoked by the client and make enterprise functionality such as transactions and resource management available to the client programmatically.
  • Message-driven beans also encapsulate and deliver enterprise functionality, but they are asynchronous and event driven. Message-driven beans listen and respond to events, and cannot be invoked by the client.

Once used to provide persistence in the EJB system, entity beans have been supplanted by the Java Persistence API. Keep reading to learn more about session beans and message-driven beans.

Session beans

A session bean is the most generic type of enterprise bean, representing a chunk of business functionality that can be called by a client. The client in this case could be another class in the local JVM or a remote call.

The EJB container manages the session bean lifecycle, which is determined by the bean's state:

  • Stateless session beans are similar to the request scope in the Java Servlet API. Stateless session beans contain a chunk of callable functionality but are otherwise stateless.
  • Stateful session beans are associated with one client only, and attach to that client's ongoing session. Stateful session beans function similarly to the session scope in the Servlet API.
  • Singleton beans are similar to the application scope in the Servlet API. A singleton session bean exists only once for each client.

Message-driven beans

Message-driven beans (MDBs) are invoked via JMS (Java Message Service) messages. JMS works like a distributed Command pattern, where the message-driven bean acts as the listener for the command. When a message arrives on a topic or queue, the message-driven bean listening on that topic is invoked.

Message-driven beans are not as commonly used as session beans, but they are powerful. Being asynchronous and event-driven, they're especially useful for long-running jobs where it's important to conserve resources.

The simplest architecture would consist of the EJB application and its container and server, which coordinate with the message service processing the MDBs. In production, your architecture would likely include a third component dedicated to consuming the beans. In development, all of these components could run on the same local machine.

Figure 1 shows a typical event-driven architecture with message-driven beans.

jw mdbs png Matthew Tyson

Figure 1. Diagram of an MDB architecture

Working with message-driven beans is more involved than using session beans. In an event-driven environment you'll typically need a message broker like ActiveMQ.

While session beans are simpler, and thus more commonly used in EJB, event-driven architectures have become popular, especially with the explosion of microservices

EJB annotations

Defining and consuming enterprise beans was a sticking point for many developers until EJB 3.0, which introduced annotations to the EJB specification. Annotations make it very easy to configure enterprise beans for a wide range of functionality found in Java EE. Keep reading to get started with EJB annotations.

@Stateless: Define a stateless session bean

In order to designate a class as a stateless session bean, you use the javax.ejb.Stateless annotation, as shown in Listing 1.

Listing 1. @Stateless annotation example


import javax.ejb.Stateless;
@Stateless
public class MyStatelessBean {
  public String getGreeting() {
    return "Hello JavaWorld.";
  }
}

This stateless bean contains a simple signature that takes no arguments and returns a string. Don't let simplicity fool you, though: this bean can do anything you need it to, including interacting with other beans, services, or your application's data layer.

@EJB: Consume a stateless session bean

Once you've defined a session bean, using it is so simple:

Listing 2. @EJB annotation example


public class MyServlet extends HttpServlet {
    @EJB
     MyStatelessBean  myEjb;
    public void doGet(HttpServletRequest request,
      HttpServletResponse response) {
        response.getWriter().write("EJB Says " + testStatelessEjb.getGreeting());
    }
}

Here, we inject the stateless bean into a servlet, and then it's available for use. Notice how the bean is identified under the @EJB annotation. The "stateless" designation tells us this bean will not track the client. Because it's stateless, we also know this bean is subject to threading if it does any work outside the invoked method.

@Remote: Define a remote EJB interface

In the above examples, I assumed the EJB and EJB client were running in the same JVM. If the enterprise bean and its client are running in separate JVMs, then the EJB must define a @Remote interface. In this case, it's up to you to define and implement the interface, as shown in Listing 3.

Listing 3. @Remote annotation example


@Remote
public interface MyStatelessEjbRemote {
    String sayHello(String name);
}

The remote interface is sent to the client to invoke. Calls to it will then be fulfilled by the EJB's server-side implementation. The MyStatelessBean example in Listing 4 implements the remote interface.

Listing 4. Implementing a remote interface


public class MyStatelessBean implements MyStatelessEjbRemote{
...
}

A remote interface is implemented just like a normal class implementing an interface. As the consumer of a remote EJB, the client application must be able to access the class definition for the remote interface. You can package the class definition for the remote interface as a dependency JAR.

Stateful sessions beans and singleton beans

The process for defining and consuming stateful @Session beans and @Singleton beans is the same as what you've seen for @Stateless beans. Remember the semantics:

  • Multiple session beans can be instantiated and used for the same client.
  • A singleton bean will exist only once for the entire application.

Thread safety and scheduling with singletons

Thread safety is built in when you're working with session beans, but both stateless and singleton beans can be accessed concurrently by multiple clients. Developers are responsible for thread safety when implementing these types of beans.

Singleton beans offer some support for thread safety via the @Lock annotation. You can use the @Lock annotation on singleton bean methods to set read/write privileges for each method. The two options are @Lock(LockType.READ) or @Lock(LockType.WRITE), which is the default.

Another useful feature of singleton beans is the ability to schedule tasks in a simple way, using the @Schedule annotation. Listing 5 shows how to schedule a task daily at noon.

Listing 5. @Schedule annotation example


@Singleton
public class MySchedulerBean {
    @Schedule(hour = "12")
    void doIt() {
      System.out.println("Hello at Noon!");
    }
}

CDI vs EJB

CDI, or Context and Dependency Injection is a newer enterprise specification that some developers have proposed could replace EJB.

At a high level, CDI offers a general-purpose component framework, while EJB stands out for its richly featured, individual components. Whereas CDI uses dependency injection to define and reference any software component, EJB components are more formally defined, with each offering a specific set of capabilities out of the box. Both specs are planned for future development as part of Jakarta EE, where the question of whether CDI should replace EJB will eventually be resolved.

Conclusion

Enterprise JavaBeans was the first specification to offer an easy way of encapsulating and re-using business logic in enterprise Java applications. Far from the heavyweight behemoth of old, EJB today is a lean, annotations-based framework that lets you access a wide range of enterprise functionality, right out of the box. Consider EJB the next time you're asked to quickly ramp up a distributed, scalable business application. You might be pleasantly surprised.

This story, "What is EJB? The evolution of Enterprise JavaBeans" was originally published by JavaWorld.

  
Shop Tech Products at Amazon