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.

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:

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.

Enterprise JavaBeans was the first component-based development model for Java EE. EJB is similar to JavaBeans in being component based, but that's where the similarity ends:

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:

A stateful session bean can only be accessed by one client at a time, so thread safety is guaranteed when you're working with this type of bean. Stateless session beans and singleton beans are more flexible, allowing concurrent connections, which must be managed by the developer. You are responsible for thread safety when working with these types of 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.

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. 

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.

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

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.

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

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.

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.

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.

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.

While it's important to know how to implement a remote interface, in practice it's more common to use a local interface. The local interface is used by default and works whenever the EJB is invoked within the same JVM context. Using the remote interface comes into play when the application is distributed across multiple JVMs.

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:

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.

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.

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.

IT World