A simple but strange problem with stateful session beans


EJB programming & troubleshooting: A simple but strange problem with stateful session beans

  1. Hi, I have a really novice problem with stateful session bean in Java EE 5. I have written a simple session bean which has a counter inside it and every time a client call this bean it must increment the count value and return it back. I have also created a simple servlet to call this session bean. For the test I opened a firefox window and tried to load the page, the counter incremented from 1 to 3 for the 3 times that I reloaded the page then I opened an IE window (which I think must be proceeded as a new client) but the page counter started from 4 and not 1 which should be for any new client and it means that the new client has access to the old client session bean. Am I missing anything here??? Isn’t it the way that a stateful session bean must react? This is my stateful session bean source. package test; import javax.ejb.Stateful; @Stateful public class SecondSessionBean implements SecondSessionRemote { private int cnt; /** Creates a new instance of SecondSessionBean */ public SecondSessionBean () { cnt=1; } public int getCnt() { return cnt++; } } And this is my simple client site servlet package rezaServlets; import java.io.*; import java.net.*; import javax.ejb.EJB; import javax.servlet.*; import javax.servlet.http.*; import test.SecondSessionRemote; public class main extends HttpServlet { @EJB private SecondSessionRemote secondSessionBean; protected void processRequest (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType ("text/html;charset=UTF-8"); PrintWriter out = response.getWriter (); out.println(""); out.println(""); out.println("Servlet main"); out.println(""); out.println(""); out.println("

    Our count is " + Integer.toString (secondSessionBean.getCnt ()) + "

    "); out.println(""); out.println(""); out.close (); } protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest (request, response); } protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest (request, response); } }
  2. Well! There will be only single instance of servlet in the whole web container.So if your are looking up and storing the session bean instance in the servlet init() method and using that sessionbean for all the request, then the servlet will use the same sesson bean for all requests.So you may lookup the session bean for the first request and store its handle in the http session fro rest of the requests from the same client. cheers, http://www.javaicillusion.blogspot.com/
  3. thank you for the answer
  4. I guess you already have the answer, I just wanted to clarify a common misconception: stateful session beans are stateful for the client that is using them. In this example, the servlet instance. As far as I understand, it is not mandatory that there will be a single servlet instance. There may be a pool of servlet instances, and when each of them is created, the instance variable you declared holding the EJB reference will be injected. As aforementioned, in order to relate a stateful bean instance with a web session, you should manually do that using HttpSession in the servlet. Servlet instance variables are a well known troublemakers, and the introduction of resource injection to servlets as well (not only EJBs) enhances that problem. In general, don't use instance variables in servlets except for finals or other well thought of cases. Also, don't inject any non-thread-safe resources to a servlet as resource injection applies to instance variables only. Read Sahoo's blog on a very similar issue: http://weblogs.java.net/blog/ss141213/archive/2005/12/dont_use_persis_1.html HTH, Amit Kasher