Discussions

I encountered the folowing situation at a client:
They have several sessionbeans that send a message to a queue, create a java object, pass it a temporary on which to wait for a reply queue for a reply.

I find this a very weird situation and imho, is something which is implicitly disallowed by the (EJB 1.1) spec which says in sec 18 that an EJB should not try to manage or start a thread (a queue session is a thread) and should not try to open a server socket (i don´t know what teh JMS implementation uses, but i guess it´s something similar to a socket).

The case I found here is not like this, it´s simply a bussiness method creating a temp queue and listening to it for one message. Eventhough it uses a helper class, it probably opens a socket to listens to a message, starts a thread (QueueSession is a thread), and uses the java.io package to read the data from the socket...

I guess I already found the answer to this. It´s quite simple actually. EJB is meant to be highly scalable. A sessionbean waiting for a message would actually block an EJB worker thread (block the tansaction) and the server would rapidly run out of resources (workerthreads in this case) resulting in a deadlock.

I use this technique ( posting a message with a temporary topic attached, and the have my SLSB block waiting for a response from the MDB to that topic ), because it was the only pattern I found to do asynchronous processing. It is in several EJB books I read, and there was quite a discussion about here on the server side.

My business problem is this: I have several independent calls to outside vendor applications, each of which take 30 seconds to run, but they run independently. I have to have a response from ALL of the vendors in order to satisfy my contract with the rest of the services. With 10 or so vendors, if I run them serially, it takes 10 * 30 secs ( 5 mins ) seconds of time from my EJB worker thread. If I post and wait for the MDBs to return, it takes 30 secs total. I realize I'm (hopefully)creating 10 threads everytime I run this, but each of those threads will finish ( I only wait a certain amount of time for each vendor response ), and in my SLSB, I timeout after 2 minutes and stop waiting for responses from the MDBs and destroy the topic.

I look at it this way: I may or may not be creating 10 MDB threads, because JMS does NOT guarantee my message will be handled immediately, so the container could decide to create exactly one MDB listening to my posting queue, and which point it basically runs the callouts to the vendors serially, or it could create 10 MDB threads and run all the requests in parallel. I assume the container is thread-pooling so it won't run out of resources. The worst that could happend is all my requests time-out if the system is overloaded.

I really hope this is not against the EJB spec. I was assured it wasn't several months ago when we figured out how to do this. If not, I'll have to find some other (horrible) solution to running my callouts in parallel.

If you are using "Asynchronous" messaging in a Request-Reply configuration, the SLSB can make a request (specifying the reply Q in the request) and block on the reply Q. This is not against the EJB spec. In fact, this is no different than a "Synchronous" call - With Request/Reply, we are just simulating a "Synchronous" call using an "Async" mechanism.

However, if you are using pure "Async" messaging, you are not supposed to use a SLSB. MDB's are designed for such a need.

Also, WAS 4.0 Extended Edition supports MDB in the form of a JMSListener component. We have had very good success with it.

<q>
If you are using "Asynchronous" messaging in a Request-Reply configuration, the SLSB can make a request (specifying the reply Q in the request) and block on the reply Q. This is not against the EJB spec. In fact, this is no different than a "Synchronous" call - With Request/Reply, we are just simulating a "Synchronous" call using an "Async" mechanism.
</q>

IMHO it is against the spec, a JMS session is a thread and thus, the SLSB is starting a Thread which it is not supposed to do. Besides, if the method runs in a transaction (which it does in my case), and the container is out of resources and the (WEBSPHERE) Transaction Inactivity Timeout has passed, the container will kill & rollback the transaction and close the temp queue. We stressed the app yesterday and this happened a lot. The container may also wait for the transaction timeout or may timeout on the Servlet/JSP side if there is no response from the EJB.

TechTarget provides technology professionals with the information they need to perform their jobs - from developing strategy, to making cost-effective purchase decisions and managing their organizations technology projects - with its network of technology-specific websites, events and online magazines.