tags:

views:

72

answers:

3

In JMS it is easy to find out if a connection is lost, a exception happens. But how do I find out if the connection is there again?

Scenario: I use JMS to communicate with my server. Now my connection breaks (server is down), which results in a exception. So far so good. If the server is up again and the connection is reestablished, how do I know that?

I don't see any Listeners which would facilitate such information.

+2  A: 

JMS spec does not describe any transport protocol, it does not say anything about connections (i.e. should broker keep them alive or establish a new connection for every session). So, I think what you mean by

Now my connection breaks (server is down), which results in a exception.

is that you are trying to send a message and you are getting a JmsException.

I think, the only way to see if broker is up is to try to send a message.

Georgy Bolyuba
Exactly - because JMS is an asynchronous protocol, the implementation can have connections established transiently - just because a connect succeeded doesn't mean the queue is now still available.
Chris Kaminski
+1  A: 

Your only option in the case of a Connection based JMSException is to attempt to reestablish the connection in your exception handler, and retry the operation.

Chris Kaminski
+2  A: 

Ahhh...the old exception handling/reconnection conundrum.

There are some transport providers that will automatically reconnect your application for you and some who make the app drive reconnection. In general the reconnections hide the exception from the application. The down side is that you don't want the app to hang forever if all the remote messaging nodes are down so ultimately, you must include some reconnection logic.

Now here's the interesting part - how do you handle the exceptions in a provider neutral way? The JMS exception is practically worthless. For example, a "security exception" can be that the Java security policies are too restrictive, that the file system permissions are too restrictive, that the LDAP credentials failed, that the connection to the transport failed, that the open of the queue or topic failed or any of dozens of other security-related problems. It's the linked exception that has the details from the transport provider that really help debug the problem. My clients have generally taken one of three different approaches here...

  1. Treat all errors the same. Close all objects and reinitialize them. this is JMS portable.
  2. Allow the app to inspect the linked exceptions to distinguish between fatal and transient errors (i.e. auth error vs. queue full). Not provider portable.
  3. Provider-specific error-handling classes. A hybrid of the pother two.

In your case, the queue and topic objects are probably only valid in the context of the original connection. Assuming a provider who reconnects automatically the fact that you got an exception means reconnect failed and the context for queue and topic objects could not be restored. Close all objects and reconnect.

Whether you want to do something more provider-specific such as distinguish between transient and permanent errors is one of those "it depends" things and you'll have to figure that out on a case-by-case basis.

T.Rob
The thing is, if I have, lets say, a GUI client which communicates via JMS with a server, it just doesn't make sense to flood the queue with messages which can't be handled anyway, because the server is down. So I guess the only realistic option would be to send a "ping" in intervals (with a low ttl) to check if it is still possible (or again) to communicate with the server. Is this an approach which you would recommend?
Mauli
That's a common approach. For example, WebSphere MQ Explorer will refresh its connection to the queue manager every 15 seconds by default. If the API call fails, reconnection is driven in the client. If that works, the GUI just takes an extra second to respond. If it fails, the GUI gets the exception and drives its own reconnect logic. In the case of applications, I usually advise people to design instrumentation calls into their API such as a non-transactional "ping" for this very reason.
T.Rob