JavaRush /Java Blog /Random EN /Introducing EJB
Анзор Кармов
Level 31
Санкт-Петербург

Introducing EJB

Published in the Random EN group
In this article we will look at EJB - Enterprise JavaBeans. This technology is part of the Java EE specification. We will touch on issues such as:
  • what is EJB;
  • what is the history of EJB;
  • what types of EJB are there?
We’ll also write a small HelloWorld application using EJB and servlets. Introducing EJB - 1This article will be useful to readers who have become comfortable with Java SE and are starting to learn Java EE. To fully understand the practical part of this article, it is recommended that you first read the article “ Setting up the local environment ”.

A Brief History of EJB

Back in 1996, when the author of this article was 5 years old, Java was already popular among developers. The reason for this was the friendly API, automatic garbage collection, etc. Java was widely used in systems responsible for the backend. However, despite all the delights of the language, programmers of that time needed certain functionality that was not yet implemented in the JDK. These needs were:
  • ensuring data persistence;
  • transaction integrity
  • competitive access to data (multi-threading control);
  • and most likely something else.
All this led to a natural growth in the population of home-grown, self-written, closed libraries. In other words, everyone fulfilled their needs as best they could. That is until IBM came out with the slogan, “Everyone should meet their needs the same way,” and released the Enterprise Java Bean (EJB) specification in 1997. It was this that made it possible to unify the development process and take the solution to typical problems (described above as needs) to the framework. Sun has been adapting IBM's brainchild for 2 years, and in 1999 released the EJB 1.0 specification. This is how the technology was born, which will be discussed further in a more applied vein.

What is EJB

EJB in a sense is a collective term that, depending on the context, can mean either the Enterprise JavaBeans technology itself in general, or some specific Enterprise JavaBean software component (bean) that is part of the EJB technology. The definition of EJB as a technology is given on Wikipedia: Enterprise JavaBeans (also often used as an abbreviation EJB) is a specification of a technology for writing and supporting server components containing business logic. It is part of Java EE. This technology is typically used when business logic requires at least one of the following services, and often all of them:
  • support for data persistence: data should be safe even after stopping the program. Most often achieved using a database;
  • support for distributed transactions;
  • support for parallel data modification and multithreading;
  • event support;
  • naming and directory support (JNDI);
  • security and restriction of access to data;
  • support for automated installation on the application server;
  • remote access.
The services listed above are an undoubted advantage of EJB technology. Another such advantage is that everything listed above works out of the box, right away. Those. the programmer does not need to think about supporting distributed transactions. The programmer only needs to think about the business logic that he is currently trying to implement. An EJB as a specific software component is a Java class with one or more annotations from the EJB specification that contains some of the business logic of the application. Annotations from the EJB specification give the tagged class certain powers, powers, and superpowers. Read more about this below.

EJB types

Let's summarize. An EJB is a regular Java class marked with one of the special annotations. Such classes are called beans. Depending on what annotation the class is marked with, it will be a representative of one or another type of EJB (beans). There are three main types of beans:
  • Message Driven Beans (message driven beans);
  • Entity Beans - defined in the JPA (Java Persistence API) specification and used to store data;
  • Session Beans.
The latter (session beans) are divided into several subtypes:
  • stateless (without state);
  • stateful (with support for the current session state);
  • singleton (one object for the entire application; starting from EJB 3.1).
Introducing EJB - 2Below we will look at each type of bean in more detail.

Session Beans

Session Beans, or session beans, are a specific type of bean. They encapsulate business logic that the client can programmatically invoke by calling the bean's methods. A method call can do:
  • locally, by another class in the same JVM as the session bean;
  • remotely, over the network, from another JVM, using Java RMI (Remote Method Invocation) technology.
The word “session” implies that the bean is available only while the server is performing a specific task and is irretrievably destroyed in the event of a server failure or shutdown. The life cycle of a session bean instance is controlled by an EJB container (you can read more about EJB containers in the first lecture of the series ). Stateless session beans do not store information about their state. This type of component can be used by various clients. Stateless beans are used to implement business processes that can be completed in one operation. For example, checking clients' credit history. Because a single bean instance can be used by multiple clients, the developer must provide thread-safe access to the bean's data. Creating a bean of this type (as well as all other session beans) is quite simple. This is a regular Java class with an annotation @Stateless. Let's give an example below:
import javax.ejb.Stateless;

@Stateless
public class StatelessEjbExample {
    public String sayHi() {
        return "Hi, I'm Stateless EJB!";
    }
}
Session beans that support the current session state (Stateful) retain information about their state between calls to it from the same client and terminate their existence upon an explicit request from the client. This is achieved due to the fact that stateful beans are unique for each client. An example of a task for which this type of bean can be responsible is keeping the shopping cart in an online store up to date for each user. The life cycle of these beans is managed by the EJB container. These beans are also destroyed when the client exits. Such beans are also quite easy to create. This is a Java class marked with the annotation Stateful. Example below:
import javax.ejb.Stateful;

@Stateful
public class StatefulEjbExample {
    public String sayHi() {
        return "Hi, I,m Stateful EJB";
    }
}
Singleton session beans are initiated once during the lifetime of the application and exist for the entire life of the application. Such beans are designed for situations in which one state must be shared among all clients. Like stateless beans, in standalone beans the developer needs to ensure that the environment inside the bean is organized in a thread-safe manner. Let's give an example of a Singleton bean, which is as easy to create as its counterparts, which were discussed above. It's easy to guess that this is a Java class with the annotation @Singleton. However, in this case you need to be careful. There are two annotations, identical in syntax, but different in purpose and located in different packages:
  • javax.ejb.Singleton
  • javax.inject.Singleton
To create an EJB, you must use the annotation from the javax.ejb. Example below:
import javax.ejb.Singleton;

@Singleton
public class SingletonEjbExample {
    public String sayHi() {
        return "Hi, I'm Singleton EJB!";
    }
}

Message Driven Beans

Message Driven Beans, or MDBs, or message-driven beans, implement some business logic, like session beans. But unlike its relatives, MDB has one important difference. Clients never call MDB methods directly. Such beans most often act as listeners for JMS (Java Message Service) messages and serve to organize asynchronous message exchange between parts of the system. An example of such a message would be a request for delivery of inventory from an automated retail system to a supply management system. Below is an example of an MDB bean. Unlike session beans, its creation is a little more interesting:
import javax.annotation.Resource;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

@MessageDriven(mappedName = "jms/TestQueue")
public class MessageDrivenEjbExample implements MessageListener {

    @Resource
    private MessageDrivenContext messageDrivenContext;

    public void onMessage(Message message) {
        try {
            if (message instanceof TextMessage) {
                TextMessage msg = (TextMessage) message;
                msg.getText();
            }
        } catch (JMSException e) {
            messageDrivenContext.setRollbackOnly();
        }
    }

}
The annotation MessageDrivenmakes our MDB class a bean. Inside the annotation, using JNDI (read about JNDI here ), the name of the JMS distribution is determined, to which our class becomes a listener. In addition, our class implements the interface MessageListenerand its method onMessage. This method will be called when some message arrives from the queue/distribution with the name defined inside the annotation MessageDriven.

Entity beans

Part of the EJB technology is the JPA specification. JPA, or Java Persistence API, is a specification that provides Object-Relational Mapping (ORM) of Java objects (Entity beans) and provides an API for storing, retrieving, and managing such objects. JPA allows you to represent data from a database as Java objects, as well as save Java objects as records in the database. Not every class can act as such an object, but Entity beans. Entity Bean is a Java class that represents a table in a database. Display (mapping) is achieved through the use of special annotations. With their help, a Java class is compared with a table in the database, as well as the fields of a Java class are compared with the fields of a database table. Here's an example of an Entity bean, with comments in the code:
@Entity // Делает данный класс Entity бином
@Table(name = "employee") // "Связывает" данный класс с таблицей employee в БД
public class Employee implements Serializable {

    @Id // Говорит о том, что поле ниже является первичным ключом
    @GeneratedValue(strategy = GenerationType.AUTO) // Определяет тип генерации значений первичного ключа
    private int id;

    @Column(name="name") // "Связывает" поле ниже с полем name в таблице employee в БД
    private String name;

    @Column (name="age") // "Связывает" поле ниже с полем age в таблице employee в БД
    private int age;

    // getters and setters...
}
It is worth noting that this type of bean makes sense to study only in the context of studying the JPA specification.

Writing an application: EJB HelloWorld

In this section, we will write a small Java EE HelloWorld application, which we will deploy on the GlassFish server. Before reading this article, it is highly recommended that you read the article on setting up your local environment .
  1. Create a new Maven project in IntelliJ IDEA.

    File -> New -> Project...

    Introducing EJB - 3
  2. Click Next .

  3. Fill in the Maven project parameters:

    Introducing EJB - 4
  4. Click Finish

  5. The project has been created and has the following structure:

    Introducing EJB - 5
The pom.xml file looks like this: Introducing EJB - 6First of all, we need to add a dependency on the Java EE API, and also specify the packaging of our project in the form of a web application archive (war). To do this, you need to change the pom.xml code to the following form:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.javarush.lectures</groupId>
    <artifactId>ejb_demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
        </dependency>
    </dependencies>

</project>
Next, you can move on to the Java code. Our application will be the simplest. We will have 1 servlet and 1 EJB. This will be a stateless session bean. Inside the EJB we will define only 1 method that will return the string “Hello World”. First of all, let's create a package com.javarush.lectures. Then, inside the package com.javarush.lectures, we will create our bean - DemoEJB. The bean code is given below:
import javax.ejb.Stateless;

@Stateless
public class DemoEJB {
    public String helloWorld() {
        return "Hello world!";
    }
}
As said earlier, everything is quite simple. Our next step is to create a servlet that will pass the value from the EJB as a response to the HTTP request. It's worth noting that servlets are not the topic of this article, but you will still need to use them to demonstrate EJB. To do this, let's create a new servlet DemoServletin the same package as the EJB. Its code is below:
@WebServlet("/helloWorld")
public class DemoServlet extends HttpServlet {

    @EJB
    private DemoEJB ejb;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write(ejb.helloWorld());
    }
}
Here are some short comments on the code. Abstract @WebServlet("/helloWorld")- defines our class as a servlet that will process HTTP requests to the endpoint /helloWorld. Our class has one field - DemoEJB ejb. This is our bean defined earlier. An annotation over a class field— @EJBperforms dependency injection (DI). Those. The ejb variable is automatically initialized with a new instance when required. Our class is a descendant of HttpServlet and overrides one of the superclass methods - doGet. This method processes HTTP GET requests and takes two parameters - HttpServletRequestand HttpServletResponse. HttpServletRequestserves to obtain information about an incoming HTTP request. HttpServletResponseneeded to generate a response to a request. Inside the method, we get the object PrintWriterfrom the response object ( HttpServletResponse), using the getWriter(). Next, we can write some value to the resulting object using the write. Which, in fact, is what we use by writing into the PrintWriter-a object the value obtained from the EJB we defined (the value is the string “Hello World!”). The client that sent the HTTP request will receive this value as a response to its request. The next step is to launch the application on the GlassFish Java EE server. To do this, we will create a new configuration, as described in the article on setting up the local environment . Below is a screenshot of the finished configuration for the current project. Make sure that you have the GlassFish server installed before starting: Introducing EJB - 7After creating the launch configuration, launch the application using the Run -> Run 'ejb_demo' menu or using the Shift+F10 hotkey . After launch, you can see its logs: Introducing EJB - 8And also the browser that opens: Introducing EJB - 9All this indicates that the application works as intended.

Conclusion

In this article we got acquainted with EJB - Enterprise JavaBeans. We considered questions such as:
  • What is EJB?
  • EJB History
  • Different types of EJBs
Recall that EJBs come in the following types:
  • Message Driven Beans (message driven beans);
  • Entity Beans - defined in the JPA (Java Persistence API) entities specification and used to store data;
  • Session Beans:
    • stateless (without state)
    • stateful (with support for the current session state)
    • singleton (one object for the entire application; starting from EJB 3.1)
We also wrote a small HelloWorld application using EJB. As a PD, you can repeat the practical part of this article yourself. And then add two more servlets to your application that will use stateful and singleton beans to receive the value.
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION