4
votes

Consider a stand-alone Java main() program (no Java EE container) which is using JMS for sending messages to a remote JMS queue.

As I understand, if the remote queue is not available for some reason (network problem, server down, queue full...), messageProducer.send(msg) throws an exception.

Do I have to implement the retry-logic myself or will the JMS-api solve this for me somehow?

  TextMessage message = session.createTextMessage();
  message.setJMSDeliveryMode(DeliveryMode.PERSISTENT);
  MessageProducer mp = session.createProducer(topic);
  mp.send(message); // Throws JMSException. How to retry, local storage etc?
5
I m not sure but looks like you have to add the retry attempt logic. - Kick

5 Answers

2
votes

In cases where there is problem with connectivity like network blip, JMS providers like WebSphere MQ have a automatic reconnection feature where the JMS client attempts to reconnect if there is a connectivity problem during execution of a API. For example if connection to JMS provider breaks during the execution Send API, JMS client attempts to reconnect to JMS provider and if a connection is established, message is sent to the provider. The reconnection attempts are transparent to JMS application meaning the application is unaware of the reconnection.

In cases where a queue is full, the application will have to handle the exception and take appropriate action.

1
votes

You have to implement retry logic yourself. Note that if connection fails it cannot be used anymore, you will need to create a new connection to retry.

1
votes

I would like to add that generally using client connections you even have to implement not only retry logic, but much more, as you could never be sure about the step there sending fails. you might put your message in successfully but server failed to send you note about that, then you got exception but message is in there... this is a bit ficticious example, but still...

I would recommend for you to implemend kind of coordinated transactions, you took message from one source (e.g. file-system or db) using transaction, then send it to queue. if everything cool you commit jms session, and then commit source (e.g. file system) operation. this might be an HA transaction, or simply pseudo HA - coordinated as I described, it is more lightweight and still provide some tolerance.

Then to implement retry logic you could just do a simple polling on resource from there your data pass on (file-system of db), so next time you poll failed message if it is rolled back - you just get it again and works with it as usual.

0
votes

If you are using WebLogic for JMS you can use the JMS SAF client to have reliable delivery from a client. More information can be found here Weblogic SAF client

0
votes

It depends on how long your client is running. If it's like a desktop app, i.e. it runs for a while, you can use a local queue on the client, and configure a bridge to take care of the reliable, once-and-only-once forwarding to the remote queue. If it's a script that is invoked only once and the quits, you'll have to handle retries, idempotency, etc. for yourself... maybe you'd be better off with a synchronous call, then.