Stateless session bean with instance variables

Preston picture Preston · Oct 27, 2009 · Viewed 24.3k times · Source

I have a stateless session bean that contains one public method, several private methods, and some instance level variables. Below is a pseudo code example.

private int instanceLevelVar

public void methodA(int x) { 
  this.instanceLevelVar = x;
  methodB();
}

private void methodB() {
  System.out.println(instanceLevelVar);
}

What I'm seeing is that methodB is printing values that weren't passed into MethodA. As best I can tell it's printing values from other instances of the same bean. What would cause this?

I should point out the code works as expected 99.9% of the time. However, the .01% is causing some serious issues / concerns for me.

I understand that if I had different public methods then I might not get the same bean back between calls, which would result in this behavior. However, in this case the only call is to the single public method. Will the container (Glassfish in this case) still swap the beans out between private method calls?

(edit) I renamed "class level" to "instance level" as this was causing some confusion.

Answer

Pascal Thivent picture Pascal Thivent · Oct 27, 2009

When I read What is a Session Bean? section of the J2EE 1.4 tutorial:

Stateless Session Beans

A stateless session bean does not maintain a conversational state for a particular client. When a client invokes the method of a stateless bean, the bean's instance variables may contain a state, but only for the duration of the invocation. When the method is finished, the state is no longer retained. Except during method invocation, all instances of a stateless bean are equivalent, allowing the EJB container to assign an instance to any client.

In your case, the call to methodB() from methodA() will be on the same instance and is equivalent to this.methodB(). I'm thus tend to say that methodB() can't output something else that the value that what was passed to methodA().

This is confirmed by the first sentence in section 7.11.8 in the EJB 2.0 spec: "The container must ensure that only one thread can be executing an instance at any time". This means you cannot come to a situation where data (in your instance variables) from different clients (threads) will be mixed. You are ensured unique access to the instance variables until methodA() has returned!

That said, I'm not saying that you don't have a problem somewhere. But I don't think that your pseudo code is equivalent.

(EDIT: Having read some comments to the OP's question, there is now clearly a doubt about the pseudo code and semantic used. I'm clarifying possible consequences below.)

As underlined by Rocket Surgeon, what do you mean exactly by class variable? Do you really mean class variable as opposed to instance variable? If yes, the pseudo code doesn't reflect it but this will clearly lead to unpredictable behavior. Actually, from section 24.1.2 (and first point) in the EJB 2.0 spec, it is clear that you are not allowed to write data to a class variable (although you can do it). There must be a good reason for this :)