We know Stateless Session Beans do not hold state by any means. Then what is the point of having a global variable in a Stateless Session Bean? Why it is not blocked in the specification (to avoid unnecessary confusion)?
If there are any practical benefit of having global variable, please explain with a piece of code fragment.
Global variables should be used when multiple functions need to access the data or write to an object. For example, if you had to pass data or a reference to multiple functions such as a single log file, a connection pool, or a hardware reference that needs to be accessed across the application.
A stateless session bean does not maintain a conversational state with the client. When a client invokes the methods of a stateless bean, the bean's instance variables may contain a state specific to that client but only for the duration of the invocation.
A stateless session bean is a type of enterprise bean, which is normally used to perform independent operations. A stateless session bean as per its name does not have any associated client state, but it may preserve its instance state.
Stateful session beans maintain the state associated with a client. Each stateful session bean serves exactly one client. Stateless session beans are intended to be simple and lightweight; that is, they are easy to develop with low runtime resource requirements on the server.
A quote from the EJB 3.1 spec
4.7 Stateless Session Beans
Stateless session beans are session beans whose instances have no conversational state. This means that all bean instances are equivalent when they are not involved in servicing a client-invoked method.
The term “stateless” signifies that an instance has no state for a specific client. However, the instance variables of the instance can contain the state across client-invoked method calls.
Examples of such state include an open database connection and an object reference to an enterprise bean object.
The emphasis is on no conversational state. They can have "other" state.
For example, I have used it to check if the load was spread equally over all instances in a cluster node:
@Stateless(name = "DemoPingSb")
@Remote(DemoPingSbIfc.class)
public class DemoPingSb implements Serializable, DemoPingSbIfc {
private final AtomicInteger instancePingCount = new AtomicInteger(0);
private final static AtomicInteger classPingCount = new AtomicInteger(0);
public DemoPingSb() {
super();
}
public String ping(final String s) {
final int local = this.instancePingCount.incrementAndGet();
final int global = classPingCount.incrementAndGet();
System.out.println("INFO: local " + local + ", global " + global
+ ", s " + s);
return s.toUpperCase();
}
}
and if there is enough load:
13:13:21,769 INFO [stdout] (http-localhost-127.0.0.1-8080-1) INFO: local 22, global 22, s hello
13:13:21,936 INFO [stdout] (http-localhost-127.0.0.1-8080-1) INFO: local 1, global 23, s hello
So there are some special cases where this feature might be useful.
Remarks
classPingCount
AtomicInteger
for instancePingCount
could by replaced with volatile int
, because (4.10.13)The container must ensure that only one thread can be executing a stateless or stateful session bean instance at any time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With