Singleton EJB support in GlassFish V3 Prelude

The GlassFish Enterprise Server V3 Prelude has been released. To get a sneak preview of some of the EJB 3.1 features in V3 Prelude, you need to install ejb container by following the instructions from my earlier blog

In this blog, I will describe one of the EJB 3.1 features available in V3 Prelude: Singleton EJBs.

One of the frequent problems that ejb developers face is to figure out how to share data between multiple components of an application. Singleton session beans are meant for this purpose. A Singleton EJB is a session bean component that is instantiated once per application. A Singleton session bean is intended to be shared by concurrent requests. In other words, all requests to the singleton will be routed to the single instance of the Singleton bean instance.

Let me demonstrate this by using a simple application. Lets say that we want to count the number of times a HelloServlet was accessed. Though there are other ways to do this, lets use a Singleton bean to accomplish the task. Note that, we can not maintain a counter inside a Stateless session bean as the container might maintain a pool of these stateless bean instances (and each will have their own counters). The Singleton session bean (called CounterBean) keeps a counter. It will have a incrementAndGetHitCount() method that increments the counter and will be called from the SimpleServletServlet.

Defining a Singleton bean

A singleton bean can be defined by using the @Singleton annotation. Note that Singleton beans can have business interfaces and interceptors just like Stateless and Stateful session beans. Also, remember that EJB 3.1 now allows optional interface view. More can be read about optional interface view in my earlier blog.

package com.sun.ejb31.test;

import javax.ejb.Singleton;
@Singleton
public class CounterBean {
    private int hitCount;

    //Note the use of synchronized keyword
    public synchronized int incrementAndGetHitCount() {
        return hitCount++;
    }

}

Handling concurrency in a Singleton

Since there is only one instance of the Singleton bean, the container routes all the requests (method invocations) to the single instance. This means that concurrent invocations are possible. The EJB 3.1 specification allows two choices to handle concurrency issues:

Container Managed Concurrency (CMC): With Container Managed Concurrency, the container is responsible for controlling concurrent access to the bean instance based on method-level locking metadata. Each business method method can be annotated with either a Read(shared) lock or Write (exclusive) lock Note: GlassFish V3 Prelude supports only BMC.

Bean Managed Concurrency (BMC): With Bean Managed Concurrency demarcation, the container allows full concurrent access to the Singleton bean instance. It is the responsibility of the bean developer to guard its state as necessary against synchronization errors due to concurrent access.

Obtaining a reference to the Singleton bean

Obtaining a reference to a Singleton bean is no different from obtaining a reference to other types of beans. In our example, we will inject a reference to the Singleton bean into our Servlet (though a JNDI lookup would have worked as well too).
package com.sun.ejb31.test;

...
import javax.ejb.EJB;

public class SimpleServlet extends HttpServlet {
   
    @EJB CounterBean counterBean;
    
    protected void processRequest(
        HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet SimpleServlet</title>");  
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>Number of times this servlet is accessed: "
                    + counterBean.incrementAndGetHitCount());
            out.println("</body>");
            out.println("</html>");
        } finally { 
            out.close();
        }
    }

    ...
    ... 

}

How to deploy and run

Assuming that you already have installed the ejb container in V3 Prelude, (if not follow these instructions)

To start the server: java -jar <install_dir>/modules/glassfish.jar

To deploy: <install_dir>/bin/asadmin deploy SimpleCounter.war

To redeploy: <install_dir>/bin/asadmin deploy --force=true SimpleCounter.war

URL to access the servlet: http://localhost:8080/SingletonCounter/SimpleServlet

Resources

EJB 3.1 public draft

SimpleCounter.war

Source files: CounterBean.java and SimpleServlet.java

Comments:

Will Singleton EJB be supported across clusters in Glassfish? Without it, we are back to solve the same problem when scaling out.

Posted by raychen on April 17, 2009 at 02:27 AM PDT #

[Trackback] EJB 3.1 (JSR 318) and Servlet 3.0 (JSR 315) are the two new JSRs in Java EE 6 (JSR 316). The EJB 3.1 specification provides multiple new features such as WAR packaging, Optional Local Business Interfaces, EJB.lite, Portable Global...

Posted by Arun Gupta's Blog on May 19, 2009 at 04:01 AM PDT #

[Trackback] EJB 3.1 (JSR 318) and Servlet 3.0 (JSR 315) are the two new JSRs in Java EE 6 (JSR 316). The EJB 3.1 specification provides multiple new features such as WAR packaging, Optional Local Business Interfaces, EJB.lite, Portable Global...

Posted by Arun Gupta's Blog on May 20, 2009 at 11:16 AM PDT #

Hi Mahesh,

I have two questions in mind regarding the Singleton Session Bean:
1. What happens to the SessionContext? Remember when Stateless Session Bean get tied to one request (or thread), the setSessionCotext() is called so that it could be used to roll back transaction or figure out the caller identity. So with the Singleton Session Bean, how many SessionContext will be there? The same one for all requests or different one for each individual request (or thread)?
2. What will happen in the Cluster environment? With the @lock(Read/Write) annotation, we could use it to allow multiple threads read/write a shared area let's say a HashMap in the same JVM. But will Singleton Beans in other JVMs in the same cluster see the changes when one instance of Singleton Bean updates its HashMap?

Posted by Bob on January 28, 2010 at 06:11 AM PST #

Bob,
look at: http://www.jbesolutions.com/blog/?p=17

Posted by Ivan on September 27, 2010 at 06:14 AM PDT #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Mahesh Kannan

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today