Since stateless session beans doesn't have states, it seems that we could get by with just one instance per bean type to serve its calls, similar to the servlet model where multiple requests are handled by a single multithreaded servlet - ignoring the possibility of SingleThreadedModel for now.
I understand that each stateless bean call needs to be remote so each "client" can connect to a different remote objects (EJBObject - keeping track of the socket connections (via the rmi stubs/skels)..etc) on the server side. But then each of these ejbobjects can simply delegate to a single bean instance, afterall, it's stateless. So what's the benefits of having a pool of stateless bean instances as described in the EJB spec?
p.s. I actually had this question in my mind 5 years ago but never seemed to find anyone or materials that could answer this satisfactorily.
Some of the reasons why I think a pool of stateless session beans is necessary (the excerpts referred below are from the O�reilly EJB book):
1)�Beans that are involved in transactions are subjected to the isolated ACID property, which means that their services cannot be shared during the life of the transaction.� [O�reilly EJB book]. If my interpretation of �services cannot be shared� is correct, then that means no other client can access the same method of the stateless session bean already involved in a transaction. Hence just having one instance of a stateless session bean will be a bottleneck if it is involved in a transaction. 2)�When a system exception occurs, the bean instance is discarded, which means that it's dereferenced and garbage collected. The container assumes that the bean instance may have corrupt variables or otherwise be unstable, and is therefore unsafe to use. The impact of discarding a bean instance depends on the bean's type. In the case of stateless session beans and entity beans, the client does not notice that the instance was discarded. These types of beans are not dedicated to a particular client; they are swapped in and out of an instance pool, so any instance can service a new request.� [O�reilly EJB book]. Hence having only one instance of a stateless bean can impact the availability of the service it offers in case a system exception occurs in one of its methods while serving a client request. 3)�If, however, the session bean is managing database data for the user, it may want to know about the beginning and ending of user transactions, so that it can cache data at the start and commit its database updates at the end. For this reason, the EJB specification allows session beans to optionally implement the javax.ejb.SessionSynchronization interface. By implementing this interface, the session bean indicates that it wants the container to notify it about the beginning and end of transactions.� [O�reilly EJB book]. This is related to point no. 1) above � �Session beans involved in transaction�. Though use of SessionSynchronization may make more sense for a stateful session bean, it is still available for stateless beans. Hence I am not sure how only one instance of a stateless session bean serving many clients can handle SessionSynchronization in a transaction. 4)�The SessionBean.setSessionContext(SessionContextcontext) method is invoked on the bean instance. This is when the instance receives its reference to the EJBContext for its lifetime. The SessionContext reference may be stored in a nontransient instance field of the stateless session bean. Everything a stateless session bean method needs to know has to be passed via the method's parameters. The only exception to this rule is information obtainable from the SessionContext and in EJB 1.1, the JNDI ENC.�[O�reilly EJB book]. Hence if only one instance of a stateless session bean is shared by multiple EJBObjects, how that one instance will be able to get a reference to its corresponding EJBObect through its nontransient sessioncontext field?
1. transactions --> not shared: transactions are associated with threads and again (see 2), if things are all running in its own method scope, we'll have no problems.
2. discarding beans on exception: This seems to be the strongest point... If we use the "multithreaded stateless bean model" (the spec mentioned nothing of it but again, it's something I wonder why), other threads from other calls can potentially wreck the bean. But if we program the bean carefully with regard to its states, everything should just be running in its own method scope. Anyway, I am wondering why the spec doesn't include this, the folks designing the servlet model did.
3. Stateless bean can't implement SessionSynchronization (yes - it's illegal, stated in pg.70 of ejb3.0 core spec.)
4. EJBContext: It's a bit tricky, but I think we could get by with using ThreadLocal to store the context for each thread. It's a bit murky, but the context can store information such as the corresponding EJBObject of a call based on the thread.
As you said in points 1 and 2, yes, if certain things are addressed in the specs, then "multithreaded stateless session beans" can exist. I was trying to highlight the probable reasons for not allowing this in "existing" specs which surround the implementation of a statless sb.
Point 3- SessionSynchronization - I missed that the specs say slsb "must not" implement SessionSynchronization. I better read the specs once again before answering next time...
Point 4- EJBContext - As you stated, it is possible to address the issue with not-so-elegant implementation around existing specs, or address the issue in the specs itself to ensure elegant implementation.
One more point for discussion: The "Concurrency" primary service (supported by an EJB server) specs state that- "Session beans do not support concurrent access. This makes sense if you consider the nature of both stateful and stateless session beans.....Stateless session beans don't need to be concurrent because they don't maintain state that needs to be shared. The scope of the operations performed by a stateless bean is limited to the scope of each method invocation. No conversational state is maintained.....In a distributed object system, problems arise when you attempt to share distributed objects among clients. If two clients are both using the same EJB object, how do you keep one client from writing over the changes of the other? If, for example, one client reads the state of an instance just before a different client makes a change to the same instance, the data that the first client read becomes invalid....EJB has addressed the dangers associated with concurrency by implementing a simple solution: EJB, by default, prohibits concurrent access to bean instances."[O'reilly EJB book]
It talks about 1) clients sharing same EJB obejct (not bean). 2) clients overwriting each others "states".
Since we are discussing about sharing "stateless" session bean "instance" (not its EJB object), these reasons for "not allowing concurrent access to slsb instance" doesn't seem to be relevant for this discussion.
To summarize: The possibility of having a multithreaded slsb doesn't sound like an inefficient way of handling slsb (assuming issues like handling system exceptions, session context etc. are addressed in the specs), unless someone throws some light on why the specs didn't and someone shouldn't consider this approach.
Yes - my focus was on exploring the thoughts behind the existing spec.
I am not sure if we are certain that there won't be an elegant solution to build a faster, better, more efficient stateless bean container even with respect to existing spec though.
To entertain the thougths further, if there's anything needed to be pooled here, it's the EJBObjects - if we have 1000 stateless beans deployed, all different types, we can share fewer EJBObjects (hence sockets) among the beans. With straight RMI, 1000 remote objects equates to 1000 listening (typically anonymous) ports/sockets. I am not sure about "exportingObject" from multiple remote objects to the same port though, my guess is the later "exportObject" will overwrite the previous ones.
Also, our entire discussion applies to MDB as well - e.g., why pool MDB when you can use one instance.
EJB is a decorated Java Bean. A Java Bean can have instance variable's and it provides getters and setters for those variables. Because of this, a bean is not thread safe. I think the way you want it to work, can be implemented using Home interface business methods. [ January 23, 2007: Message edited by: Devender Thareja ]
Perhaps the reason for such an implementation might be the fact that container services - the very reason why we use EJB's - are made available at the instance level and not at the thread level. And these services i believe are more resource intensive than whats done in case of servlets.
Take for instance transaction support - incase of servlets for instance, when we create connection objects in init method and execute the transactions in service method - what happens .. Multiple threads, single instance, same transaction and...Perhaps to avoid such conflicts we go in for pooling of instances.