- Stands for Enterprise Java Bean
- It’s a server-side component that encapsulates the business logic of an application
EJBs are often combined where they call each other to execute business logic on the Java EE server
EJBs clients can be :
- Web-tier components (local or remote)
- Remote clients (over RMI)
- Web service clients (over HTTP/SOAP)
The idea of EJBs is to move the business logic out of the web-tier and into a separate layer that exclusively focuses on modeling the business domain and the related operations.
Two main components in EJB:
- Session Beans perform business logic, manages transactions and access control.
- Message Driven Beans perform actions on event (receive a JMS message) associated to JMS Queues and JMS Topics. They are asynchronous.
- Different life-cycles for each type of component
- EJB components specify how they behave with their supporting container using metadata (mostly annotations, XML descriptors are still available but optional)
![]() | Note |
---|---|
Entity beans still exists but they are not considered as Enterprise Beans since they are now managed by Java Persistance API |

EJBs run within a EJB Container, a run-time environment of a Java EE app server
The EJB Container provides system-level services, such as:
- Transactions (including distributed transactions)
- Security
- Persistence (via JPA)
Just like the web-tier components run in the Servlet container, EJBs require the services of a EJB container - i.e. EJBs cannot run on their own.
![]() | Note |
---|---|
Before EJB 3.0, Entity beans used to be managed by the EJB container. Now, Entity beans are managed by a persistence provider. |
Simplify the development of large and distributed enterprise applications:
- Bean developers focus on business problems, and the container takes care of the rest, most notably transactions and security. Persistence is managed by JPA.
- Paradigm for separating the business logic from its presentation, which simplifies the UI development
- EJBs are portable, easily integrate with existing beans, and run on any Java EE AS
EJB technology is a good candidate for the following situations:
- Applications with complex business logic that must be scalable. Transparent distribution of load across multiple server instances is at core of EJB
- Applications that require [distributed] transactions to ensure data integrity. The EJB container provides the necessary mechanisms that manage the concurrent access to shared objects
- Applications that are accessed by a variety of clients. It is easy to provide remote access to EJBs from various, numerous, and very thin clients
Prior to EJB3
EJB applications were harder to test as they depend heavily on the container services
- Automated unit testing was a challenge
EJB applications were harder to develop and deploy
- Required complex deployment descriptors and stub classes (often dependent on the app server)
- Slower development-deployment-test cycle lead to reduced developer productivity
Remote
interfaces of EJBs could have negative impacts on the OO design- Due to performance issues, EJBs would often make use of coarse-grained interfaces
-
All parameters had to be
Serializable
- Parameters were often passed by copy (as opposed to by reference) which lead to discontinuity
While EJB3 is a huge improvement over EJB 2.1, many of these drawbacks still apply to some degree
- EJB is still considered a heavyweight technology
- Using EJB reduce the choice of app servers (e.g. cannot use Tomcat)
- Many developers opt for simpler and leaner IoC/DI containers such as Spring Framework or Guice
- Reusable components that contains business logic. Clients can interacts with Session Beans locally or remotely.
- To access a session bean, the client invokes its public methods
Stateless Session Bean
- Performs a task for a client
- Is not attached to a client (no client state maintained)
- Can implement a web service
Stateful Session Bean
- Represents a single client inside the application
![]() | Note |
---|---|
As its name suggests, a Session Bean is not shared. It can only have one client at a time. A Session Bean is not persistent. |
Stateless Session Beans
- Maintain the client state only for the duration of the method invocation
- When the method returns, the bean appears to terminate as well
- Do not need to persist the state to the secondary storage
- Are more scalable because they can be shared
- Are more common in Java EE applications
- Could represent actions such as: sending email, converting currency
Stateful Session Beans
- Maintain the conversational state with the client, which survives across multiple method invocations
- Release their state once the client removes the bean or terminates
- Can temporarily persist their state to the secondary storage - for stability reasons
- Could represent temporary entities such as shopping carts
An interceptor is a method that intercepts an EJB "business" method invocation on
- Stateless session bean
- Stateful session bean
- Message driven bean
Particularly useful to perform fine-grained activities such as logging, performance metric collection, parameters validation, etc…
- Could also be use for implementing custom transactions or security semantics
Interceptors can be bound to an EJB in three ways:
- As a class-level interceptor
-
As a method-level interceptor with the
javax.interceptor.Interceptors
annotation:@Interceptors(value=package.InterceptorClassName.class)
Declared in
ejb-jar.xml
:... <assembly-descriptor> <interceptor-binding> <ejb-name>*</ejb-name> <interceptor-class>package.InterceptorClassName</interceptor-class> </interceptor-binding> ... </assembly-descriptor> ...
An interceptor class is separate from the bean-itself
-
It defines
@AroundInvoke
methods that are invoked around the invocations of the bean methods - Must have a public no-arg constructor
-
It defines
- Any number of interceptor classes may be defined for a bean class
- Represent a table in a relational database
- Each instance of this entity corresponds to a row in that table
- Each entity has a unique identifier - this allow clients to locate a particular instance of this entity
- Entities can have relationship, for example, a Zoo instance will contain several Animal instances
![]() | Note |
---|---|
Remember that now, in EJB 3.0, Entity Beans are now managed by JPA. |
Entity class must match the following requirements:
-
The class have to be annotated with the
javax.persistence.Entity
annotation - Must have a public or protected, no-argument constructor. The class can have other constructors
Can’t be declared
final
. Methods or persistent instance variables can’t befinal
- This allows JPA to automatically create proxy objects (as needed) to manage semantics such as lazy-loading
- Persistent instant variables have to be declared private, protected or package-private
- Properties have to be accessed directly or through getters/setters
-
The class have to be annotated with the
![]() | Note |
---|---|
If a developer doesn’t want to persist a property of a class, he can simply annotate this property with the |
- An enterprise bean that processes application messages asynchronously
- Implemented as a JMS listener
- Similar to Stateless Session Beans
- MDBs retain no session state for a specific client
- All instances of the same MDB are equivalent
- A single MDB can process messages from multiple clients
- Unlike Session Beans, MDBs expose no interface and are not accessed directly
To use a MDB, a client simply creates a JMS Message and sends it to the Destination on which the MDB is listening.
- Except for MDBs, Session Beans require clearly defined interfaces to be accessed by a client.
- Interfaces serve as a layer of insulation allowing transparent access and future changes in the implementation
- Session Beans can have more than one business interface
Depending on the client access, these interfaces can be:
- Remote Interface
- Local Interface
- Web Service Interface
- Clients can run on separate JVMs or servers
- Client can be a web component, an application client, or another enterprise bean
- Bean location is transparent to clients
- Bean loosely coupled with related beans
- Bean can be distributed - better scalability
- Bean must also implements its interface
- Clients must run in same JVM
- Client can be a web component or another enterprise bean
- Bean location is not transparent to clients
- Bean is tightly coupled with related beans
- Works only for stateless session beans
- Clients run on separate JVMs or servers
- Accessed by a web service client that uses the correct protocols (SOAP, WSDL, HTTP)
- Bean location is transparent to clients
- Clients can be implemented in any language (i.e. does not have to be Java)

- Instances created by the EJB container
- These instances are kept into a pool of ready instances
- A method call is made by a client
- The container assign a ready instance from the pool to the client for the duration of the call
- The SLSB instance is then returned to the pool.
![]() | Note |
---|---|
If the container is not able to create more beans, our client has to wait for a ready instance before the EJB timeout. |

- A client session is started
- Default constructor is invoked
- Ressources are injected (if any)
-
@PostContruct
annotated method is called - Now the SFSB is in cache and ready to execute any business method invocation from the client
![]() | Note |
---|---|
The container will remove the SFSB instance from the cache, serialize it and move it into a temporary storage the SFSB instance when the client remains idle for a certain time. This is called Passivation |

- A message is received
- The contained checks any Message Driven Bean instance available in the pool
- If available, JBoss use this MDB
-
When
onMessage()
complete, the MDB instance is returned to the pool
![]() | Note |
---|---|
You can see that the MDB life cycle creation is the same as the SLSB. The difference is here if an instance can’t be created, the request is blocked until another MDB becomes available. |
-
Previous versions of EJB (1.x - 2.x) can be configured in the
<configuration-set>/conf/standardjboss.xml
For EJB 3.x, the configuration file is
<configuration-set>/deploy/ejb3-interceptors-aop.xml
- This file is divided into domains.
-
Each of these domains contains actions, called
Interceptors
.
Each call to a domain goes through a stack of Interceptors to the target method. After execution, the call unwinds through the stack in reverse order.
How to configure the Stateless Session Bean pool size? In the deploy/ejb3-interceptors-aop.xml
:
... <domain name="Stateless Bean" extends="Intercepted Bean" inheritBindings="true"> ... <annotation expr="!class(@org.jboss.ejb3.annotation.pool)"> @org.jboss.ejb3.annotation.pool (value="ThreadLocalPool", maxSize=30, timeout=10000) <!----> </annotation> ... </domain> ...
|
Table 1. An example table
Attribute | Description |
---|---|
CreateCount | Number of create invocations since last call |
InvokeStats | Informs about concurrent executing calls, methods invoked (how many times, time to process…) |
CurrentSize | Current size of the pool (ready to be used) |
RemoveCount | Number of remove invocations since last call |
MaxSize | This is the maximum size of the pool |
AvailableCount | How many instances are available in the pool? |
Here you can see that MaxSize matches what we defined before (30 is also the default).
![]() | Note |
---|---|
You can also apply these configurations in other domains. |
What if you just want to apply a configuration to a single component and not all EJBs?
-
The easy way is annotate your class. Example:
@PoolClass(value=org.jboss.ejb3.StrictMaxPool.class, maxSize=10, timeout=10000)
-
The other way is to create a custom domain containing the configuration. Then, you apply the custom domain to your EJB in
jboss.xml
file deployed along with your application.
Configuration will happen in the Stateful Bean domain in the ejb3-interceptors-aop.xml
How to configure the Stateful Session Bean cache?
The configuration is split in two parts
- Non-clustered cache configuration
- Clustered cache configuration
... <domain name="Stateful Bean" extends="Base Stateful Bean" inheritBindings="true"> <!-- NON Clustered cache configuration --> ... <annotation expr="class(*) AND !class(@org.jboss.ejb3.annotation.CacheConfig) AND !class(@org.jboss.ejb3.annotation.Clustered)"> @org.jboss.ejb3.annotation.CacheConfig (maxSize=100000, idleTimeoutSeconds=300, removalTimeoutSeconds=0) </annotation> ... <!-- Clustered cache configuration --> ... <annotation expr="class(*) AND !class(@org.jboss.ejb3.annotation.CacheConfig) AND class(@org.jboss.ejb3.annotation.Clustered)"> @org.jboss.ejb3.annotation.CacheConfig (name="sfsb-cache", maxSize=100000, idleTimeoutSeconds=300, removalTimeoutSeconds=0) </annotation> ... </domain> ...
With the provided EJB
my-ejbs.jar
and the web appCurrencyConverterWeb.war
, build an EAR file.Note An EAR file is a standard JAR file (Zip file), with the
.ear
extention. It’s used for packaging one or more modules into a single archive.Here is the hierarchy of you EAR file:
- META-INF/
META-INF/application.xml
<?xml version="1.0" encoding="UTF-8"?> <application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:application="http://java.sun.com/xml/ns/javaee/application_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd" id="Application_ID" version="5"> <display-name>CurrencyConverterApp</display-name> <module> <ejb>my-ejbs.jar</ejb> </module> <module> <web> <web-uri>CurrencyConverterWeb.war</web-uri> <context-root>CurrencyConverterWeb</context-root> </web> </module> </application>
- my-ejbs.jar
- CurrencyConverterWeb.war
- Deploy it to JBoss.
- Take a look at JBoss console to see how components are deployed
- Then go to http://localhost:8080/CurrencyConverterWeb to try if your EAR file works well.
You now know how to deploy EAR application with an EJB.