injecting a stateful bean is not really that useful, because, as you said, stateful beans cannot have concurrent access and you will get an exception. Stateless beans should be fine to store a reference.
Just to clarify, the older specifications do not make the distinction between a stateful and stateless session bean -- they make it sound like you can never have two threads calling the same session bean reference at the same time.
I agree that it makes no sense, but that's what it says. Will 3.0 relax this restriction (the current 3.0 draft has no mention of this)? If it is in fact allowed for stateless session beans, does JBoss serialize calls to the same instance, or are the concurrent calls simply assigned to different instances of the bean to handle (which would be preferable)?
Here's the quote from section 7.12.10 in the EJB 2.1 specification (identical to section 7.11.8 in the 2.0 specification):
The container must ensure that only one thread can be executing an instance at any time. If a client request arrives for an instance while the instance is executing another request, the container may throw the java.rmi.RemoteException to the second request if the client is a remote client, or the javax.ejb.EJBException if the client is a local client.
Note that a session object is intended to support only a single client. Therefore, it would be an application error if two clients attempted to invoke the same session object.
One implication of this rule is that an application cannot make loopback calls to a session bean instance.
FYI -- I've asked this question to the EJB 3.0 EG. I'll post their reply here.
Here's the email:
My question relates to session bean thread safety in EJB 3.0 ? that is, multiple threads using the same EJB reference to access the bean. The 2.0 and 2.1 specifications specifically required the container to throw an exception in this case (see section 7.12.10 of the EJB 2.1 specification). While this makes perfect sense for stateful session beans, its usefulness is less convincing for stateless session beans (but the specification made no distinction).
The EJB 3.0 specification doesn?t make any reference to thread safety for stateless session beans (it does require the container to synchronize calls to stateful session beans). Does this imply that, as the creators of the specification, you intend for the EJB 3.0 container to assign each concurrent call to the EJB reference to a different instance of the bean? This would essentially just treat concurrent calls to the same reference as if they had been made to difference references and put them through the normal EJB lifecycle.
This would be the optimal solution, since a client could simply lookup the bean?s reference once, and then use that over-and-over from wherever that bean?s functionality is needed without regard for synchronization issues. This is especially useful if EJB session bean injection is ever allowed into servlets ? and in the meantime, it is useful to lookup the session bean once in the init() method of the servlet.
Any information on your plans as it relates to session bean thread safety / synchronization would be appreciated.
Hate to bring this up again, but with the release of the PR draft, the EJB 3.0 specification now prohibits this as well -- you can't safely use a single EJB session bean reference from multiple threads, which means looking up a Session bean from init() in a servlet wont work.
There is a footnote that makes an exception, but says clients can't depend on it.
Bill -- any feedback on what we should do? Should we lookup SB references on each hit to the servlet? Seems costly at best.
I've had to face this problem with Preview 5. I'm actually using a reference for each end user and storing it into the HTTPSession instead of the ServletContext. This is not enough to prevent concurent calls anyway so that I had to place a synchronizing Java Bean in front the stateful beans to prevent concurent calls. I did not do it for stateless beans and had no problems.
It is indeed important to know if calls to stateless beans on a on a single reference have to be synchronized. On the other hand I read that some J2EE servers like WebLogic can be configured to synchronize calls on session beans. This would greatly simplifies client software development but is useless for me if just some app servers can do it. Especially if JBoss does not.
Just a user point of view
Actually, it kinda stinks even if they synchronize the calls on stateless beans -- you don't want all of your servlets to be tied up waiting for synchronization of a single SLSB. Imagine 50 web clients all waiting to use that one bean...
Bill -- please tell us what happens when we make multiple calls to the same SLSB reference... is it sync'd on a single SLSB, or does the EJB container just pool each request to a different instance?
Does the same apply for @Remote interfaces?
No matter what interface is used they end up in the StatelessInstanceInterceptor which calls get on the pool. The default pool implementation is the ThreadLocalPool
Excellent implementation as far as usability goes for us users, but doesn't this break the specification, which requires you to either serialize the calls or throw an exception if two calls are made against the same EJB SB reference?