EJB 3.x : Lifecycle and Concurrency models (part 1)

Java EE component life cycle and concurrency related details might not be new for seasoned professionals, but it is something which can take time to sink in for beginners.

concurrency

As far as EJBs are concerned, understanding their life cycle (and related concurrency scenarios) is extremely critical in order to ensure appropriate usage and solution design using EJBs. It’s easy to misuse them !

 

bean-lifecycle

Bean Life Cycle

 

I’ll quickly cover Stateless and Stateful beans in this post and skip Lima Beans for the time being 😉

  • Stateful Session Beans – life cycle + concurrency handling
  • Stateless beans – concurrency model only, since I had briefly covered the lifecycle in one of my previous posts.

What are the distinct states in the life cycle of a Stateful Session Bean?

  • Does Not Exist
  • Ready
  • Passivated

How do the states change? What triggers them?

Here is a quick tabular snap shot and a high level diagram. For more details, read on . . .

stateless-ejb-lifecycle

Stateless Session Bean Life Cycle State diagram

Note: DNE – Does Not Exist, R – Ready, P – Passivated, SFSB – Statelful Session Bean

State Transition Triggers Callbacks
DNE to R When a SFSB instance is first accessed via JNDI or DI @PostConstruct
R to DNE Container shuts down, client invokes method annotated with @Remove, the bean reaches idle time out threshold designated by DD or @StatefulTimeout @PreDestroy
R to P The EJB container passivates idle beans and removes them from active memory based on specific algorithms @PrePassivate
P to DNE The bean reaches idle time out threshold designated by DD or @StatefulTimeout Note: @PreDestroy annotated method is NOT invoked
P to R When the client invokes a SFSB instance after it is passivated but has not timed out yet @PostActivate

Note: If a SFSB throws an exception during request processing, its instance is destroyed i.e. it goes to a DNE state. The @PreDestroy annotated method is not invoked in this case

Now that we have some idea about the life cycle of a SFSB, let’s try to take a look at how do these beans behave under load i.e. when the application is used by multiple users at a time which translates into concurrent access of SFSB instances

Stateful Session Beans: Concurrency Management

Thread safety is one of the core features of EJBs. The point to be noted is that this thread safety is free of cost and does not need any concurrency related constructs to be coded in by the bean developer himself (there are a few exceptions). As far as SFSB are concerned, the EJB container ensures that only one thread can access a bean instance at a particular time.

In this example, we are trying to simulate concurrent access to a single instance of a SFSB by invoking a test Servlet via JMeter. The Servlet injects the bean via DI and calls a method on it. The SFSB method just uses a Thread.sleep() to pretend as if it’s executing something.


package com.abhirockzz.wordpress.ejb.lifecycle.stateful;

import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Stateful;

@Stateful
public class MyStatefulBean {

    public MyStatefulBean() {
    }

    public void act() {
        System.out.println("Entered MyStatefulBean/act() on " + new Date().toString() + " . SFSB instance " + this.hashCode() + " Thread : " + Thread.currentThread().getName());
        try {
            Thread.sleep(2000);
        } catch (InterruptedException ex) {
            Logger.getLogger(MyStatefulBean.class.getName()).log(Level.SEVERE, null, ex);
        }

        System.out.println("Exit MyStatefulBean/act() on " + new Date().toString() + " . SFSB instance " + this.hashCode() + " Thread : " + Thread.currentThread().getName());

    }
}

 

 


package com.abhirockzz.wordpress.ejb.lifecycle.stateful;

import java.io.IOException;
import java.util.Date;
import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "SFSBTestServlet", urlPatterns = {"/SFSBTestServlet"})
public class SFSBTestServlet extends HttpServlet {

    public SFSBTestServlet() {
    }

    @Inject
    MyStatefulBean mySFSB;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("Entered SFSBTestServlet/doGet() on " + new Date().toString() + " . Servlet instance " + this.hashCode() + " Thread : " + Thread.currentThread().getName());
        mySFSB.act();
    }

}

 

sfsb-jmeter-1

HTTP GET request via JMeter

 

sfsb-jmeter-2

Concurrent request simulation via JMeter

 

Observations

  • Since a Servlet itself is not thread safe, multiple threads will in fact enter the doGet() method
  • A single instance of the SFSB (evident via the hashCode result) in being accessed concurrently (see the thread names in the logged statements)
  • Only one thread will be able to access the SFSB instance though – other threads wait for their turn while the SFSB method returns. This delay is noticeable via the log statements on the console

 

sfsb-result

Console logs

 

What about Stateless Beans?

These beans are inherently thread safe. Why? It is because by default, the container makes sure that each new request is served by a new instance of the bean. Remember, that a client can obtain a reference to stateless bean in 3 possible ways – DI, JNDI or via a remote interface (RMI). In all these cases, it is the container (proxy) which intercepts the call – thus, even if multiple threads are seemingly accessing the same bean instance, its actually not the same one 😉


package com.abhirockzz.wordpress.ejb.lifecycle.stateless;

import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Stateless;

@Stateless
public class MyStatelesslBean {

    public void act() {

        System.out.println("Entered MyStatelesslBean/act() on " + new Date().toString() + " . SLSB instance " + this.hashCode() + " Thread : " + Thread.currentThread().getName());
        try {
            Thread.sleep(2000);
        } catch (InterruptedException ex) {
            Logger.getLogger(MyStatelesslBean.class.getName()).log(Level.SEVERE, null, ex);
        }

        System.out.println("Exit MyStatelesslBean/act() on " + new Date().toString() + " . SLSB instance " + this.hashCode() + " Thread : " + Thread.currentThread().getName());
    }
}

 


package com.abhirockzz.wordpress.ejb.lifecycle.stateless;

import java.io.IOException;
import java.util.Date;
import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "SLSBTestServlet", urlPatterns = {"/SLSBTestServlet"})
public class SLSBTestServlet extends HttpServlet {

    @Inject
    MyStatelesslBean slsb;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        System.out.println("Entered SLSBTestServlet/doGet() on " + new Date().toString() + " . Servlet instance " + this.hashCode() + " Thread : " + Thread.currentThread().getName());

        slsb.act();

    }

}

 

Observations

  • Since a Servlet itself is not thread safe, multiple threads will in fact enter the doGet() method
  • Different instances of the SLSB (evident via the hashCode result) are being picked by the container to manage concurrent requests (see the thread names in the logged statements).
  • In spite of concurrent requests, each request thread is getting serviced by a new instance
slsb-result

Console logs

 

That’s all for now! I am planning to cover Singleton Session beans in a future post. Stay tuned . . . .

Thanks for reading! 🙂

 

About Abhishek

Currently working as a Senior Product Manager in the Oracle Cloud Application Development team with a focus on Oracle Cloud PaaS portfolio. When not hovering in the clouds, I stay grounded with Java EE
This entry was posted in Java, Java EE and tagged , , , , , , , . Bookmark the permalink.

8 Responses to EJB 3.x : Lifecycle and Concurrency models (part 1)

  1. Pingback: EJB 3.x : Lifecycle and Concurrency models (part 2) | Object Oriented . .

  2. quartaela says:

    Thanks. This is a great post !! I want to a question if you don’t mind. In my internship I was developing Restful Web Services on Jboss application container. The issue was we had’t been using any @Stateful or @Stateless annotations. We were only using annotations for java’s own CDI which like @Named, @Inject, @PostConstruct etc. And were weren’t using any java synchronization modifiers also. When I asked my senior how we handle with concurrency issues for transactions, he told me hat JBoss automatically distributes requests to threads from thread pool, and those threads are handles with concurrency. Is that totally true ?

    Like

    • Abhishek says:

      Thank you for reading and really glad you liked the content!

      Concurrency and transactions are really different topics in my opinion. I am not going to mix them up….

      JBoss is an application server, but to be honest, JBoss or any application server does not do anything automatically. What I mean to say is that services like concurrency (thread safety), transactions etc are provided by components of a container (or maybe you can call them sub containers, virtual containers or simply run time environments) e,g. the EJB container, CDI container etc. So its really the container which renders these services to you if you ask for it. You cannot expect a plain old java class executing in an application server to be thread safe 🙂 What you can do is request the container to do so – in Java EE its best achieved by use of annotations specific to that container e.g. @Stateless in case of EJBs

      Coming to your scenario of a Restful Web Service

      1. One cannot use @Stateful with a REST (JAX-RS resources)
      2. @Stateless can be used and will satisfy all concurrency and transaction related requirements without any additional overhead (convention by configuration)
      3. By default, a new instance of a JAX-RS resource class is instantiated with every HTTP request. If your resource class implementation is stateless (as per REST requirements), multi-threaded access should not be a concern. However, if state is being stored in the fields of your JAX-RS resource classes (e.g. via static fields), then you would need to implement explicit thread safety

      Just to repeat my point – nothing is done automatically. You need to give some hint to the container (mostly in the form of annotations) and you are good to go!

      Hope this helped. All the best!

      Like

  3. Pingback: Java Weekly #9: Money, retired DTOs, JSR for MVC, JDK tools aand more... - Thoughts on Java -

  4. lolero2 says:

    Thank you very much for all your writing! I am starting to learn Java EE and reading some your articles has been very helpful in understanding concepts for which I had found no useful information anywhere else. However, there are some scenarios for which the lifecycle of the EJBs is still not clear to me and I would like to ask you some questions about this.

    Could you please shed some light on the definitions of a ‘client request’ and a ‘session’?
    I ask because I would like to inject some session beans into a singleton EJB and am not sure what their lifecycle would be in this case. All the information I have found mentions client requests (as in remote applications or servlet-type calls) but I have not been able to find what exactly constitutes such ‘clients’, ‘requests’, and ‘sessions’. Hence, my next question:
    What would be the lifecycle of a SFSB or a SLSB when it is injected into a singleton EJB? Considering that, as I understand, one instance of the singleton is always active, would the session beans that it instantiates remain always active as well? Would a ‘client request’ to the session beans be their injection as an instance variable of the singleton or a call to one of their methods?
    In your example of the SLSB, would it make sense (is it possible? would it make a difference?) to inject the SLSB as a local variable inside the doGet method, as opposed to as an instance variable of the servlet class (since each call uses a different instance)? Would it make sense to do it with a session bean injection into a singleton?

    Like

    • Abhishek says:

      Thanks for reading the post and glad you found it useful. I’ll try and answer this in short

      Stateless beans: if you inject them (using @Inject @EJB), the container can give you ANY instance from the pool (which is free) e.g. two consecutive requests might result in you getting the same instance (from JVM heap) or they might be different instances – hence the name Stateless ( you cant depend on the instance specific state). It is the same even if you inject it in Servlet or Singleton EJB
      Stateful: In this case, its a unique instance per client. Now what’s a client ? It ‘s the component which in using/injecting the Stateful bean instance e.g. if a Singleton bean injects a Stateful bean, it will ALWAYS be attached to the same instance of the Stateful bean since the client (Singleton bean) itself is the same – as I said, unique instance per client. E.g. if you inject a Stateful bean in a request scoped JSF managed bean, you’ll get a unique instance of the Stateful bean per invocation of the JSF managed bean (since its request scoped)

      As far as injecting vs. using a SLSB instance in servlet is concerned – it does not make sense to localize the use of a SLSB within a servlet method (but its definitely possible). The entire point of using the SLSB is to get behaviour ‘without’ state

      You can also refer my free ebook on EJBs 🙂 This might sound like a shameless plug, but I am just pointing it out not because it perfect, but because it’s free and simple (specially for beginners). Mind you, there are other awesome resources out there ! 🙂

      HTH
      Cheers!

      Like

  5. There is a wrong titile or wrong picture for a stateless bean lifecycle – it cannot be passivated. Container can passivate statefull beans only

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s