Question

The title might be confusing but this is what I want to accomplish. I want to send a jms message from 1 ejb to another, the 2nd ejb has a message listener and this is now working properly. But I wanted the 1st ejb to create a temporary destination queue where the 2nd ejb would respond - this is also working properly.

My problem is in the 2nd ejb, it's calling a 3rd party web service that on some occasion would respond after a long time, and the temporary queue should expire on that time. But the problem is it doesn't according to java.net: http://java.net/projects/mq/lists/users/archive/2011-07/message/22

The message hasn't been delivered to a client and it expires -- in this case, the message is deleted when TTL is up.
The message is delivered to the JMS client (it's in-flight). Once this happens, since control is handed to the jms client, the broker cannot expire the message.
Finally, the jms client will check TTL just before it gives the message to the user application. If it's expired, we will not give it to the application and it will send a control message back to the broker indicating that the message was expired and not delivered.

So, it was received but no reply yet. Then on the time where it would write to the temporary queue it should already be expired but for some reason I was still able to write to the queue and I have the ff in my imq log:

1 messages not expired from destination jmsXXXQueue [Queue] because they have been delivered to client at time of the last expiration reaping

Is there another implementation where I can detect if the temporary queue is already expired? So that I can perform another set of action? Because my problem right now is ejb2 respond late and there is no more jms reader from ejb1 because it's already gone.

Was it helpful?

Solution

It works now, my solution was to wrap the 1st Stateless bean (the one where the first jms message originates) inside a bean managed transaction. See code below:

@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
@LocalBean
public class MyBean {
    public void startProcess() {
        Destination replyQueue = send(jmsUtil, actionDTO);
        responseDTO = readReply(jmsUtil, replyQueue, actionDTO);
        jmsUtil.dispose();
    }

    public Destination send(JmsSessionUtil jmsUtil, SalesOrderActionDTO soDTO) {
        try {
            utx.begin();
            jmsUtil.send(soDTO, null, 0L, 1,
                    Long.parseLong(configBean.getProperty("jms.payrequest.timetolive")), true);
            utx.commit();
            return jmsUtil.getReplyQueue();
        } catch (Exception e) {
            try {
                utx.rollback();
            } catch (Exception e1) {

            }
        }
        return null;
    }

    public ResponseDTO readReply(JmsSessionUtil jmsUtil, Destination replyQueue,
                SalesOrderActionDTO actionDTO) {
            ResponseDTO responseDTO = null;
        try {
            utx.begin();

            responseDTO = (ResponseDTO) jmsUtil.read(replyQueue);

            if (responseDTO != null) {
                //do some action
            } else { // timeout
                ((TemporaryQueue) replyQueue).delete();
                jmsUtil.dispose();
            }
            utx.commit();
            return responseDTO;
        } catch (Exception e) {
            try {
                utx.rollback();
            } catch (Exception e1) {
            }
        }
        return responseDTO;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top