Issue Details (XML | Word | Printable)

Key: SPR-5002
Type: Improvement Improvement
Status: Resolved Resolved
Resolution: Fixed
Priority: Major Major
Assignee: Juergen Hoeller
Reporter: Henric Larsson
Votes: 0
Watchers: 2
Operations

If you were logged in you would be able to see more operations.
Spring Framework

DefaultMessageListenerContainer isn't logging linked jms exception or destination

Created: 14/Jul/08 05:15 AM   Updated: 17/Jul/08 02:48 AM   Resolved: 17/Jul/08 02:48 AM
Component/s: SpringJMS
Affects Version/s: 2.0.8, 2.5.1, 2.5.2, 2.5.3, 2.5.4, 2.5.5
Fix Version/s: 2.5.6

Time Tracking:
Not Specified

Virtual Machine: Sun JVM - 1.6
Platform: Standalone


 Description  « Hide

When the DefaultMessageListenerContainer catches a jms exception, it never logs the linked exception which is the exception that contains usable information when running Websphere MQ.

It would also be helpful if it included the destination name in the log output in order to identiy which destination failed.

Code snippet to illustrate how it could be done:

if(ex instanceof JMSException)

{ ex = new JMSException( String.format( "JMS problem. Destination [%1$s], Linked ex: [%2$s]", getDestinationName(), ((JMSException) ex).getLinkedException().getMessage() ) ); }

logger.error("Setup of JMS message listener invoker failed - trying to recover", ex);



Henric Larsson added a comment - 14/Jul/08 06:34 AM

There's a few places this needs to go into, in my customisation of it I've added it to the following methods, although it may be done in a more centralized manner.

refreshConnectionUntilSuccessful()

AsyncMessageListenerInvoker.initResourcesIfNecessary()

handleListenerSetupFailure(Throwable ex, boolean alreadyRecovered)


Juergen Hoeller added a comment - 15/Jul/08 12:19 PM

Good point! The JMS API's JMSException class is unfortunately not implemented in a way that would be compatible with the JDK 1.4 exception changing mechanism...

I've revised the log messages in refreshConnectionUntilSuccessful and handleListenerSetupFailure accordingly; to be released in Spring 2.5.6.

What exactly did you do to initResourcesIfNecessary - there is no logging code there, at least not in the most recent version of the code?

Juergen


Henric Larsson added a comment - 16/Jul/08 04:10 AM

I've wrapped the whole method in a try catch, that rewrites any JMSException to include destination name and the linked exception. This is mainly because we use MQ Series, and it's default exception messages are more or less useless Not naming queue name, and putting the actual error code in the link exception rather than the thrown exception. Can't rememeber now why I had to stick this in this method too, but it may me a different code path when the thing tries to initialise or recover.

Here's the code I've added, it's not ideal, but it meets my requirements.

private void initResourcesIfNecessary() throws JMSException
{
try{ ... Original code goes here..... }
catch(JMSException jms)

{ Destination dest = getDestination(); String destName = dest != null ? dest.toString() : "null"; String linked = jms.getLinkedException().getMessage() != null ? jms.getLinkedException().getMessage() : "null"; JMSException r = new JMSException( String.format( "%1$s, destination: '%2$s', linked: %3$s", jms.getMessage(), destName, linked )); r.setLinkedException(jms); throw r; }

}


Juergen Hoeller added a comment - 16/Jul/08 09:09 AM

Hmm, as far as I can see (and as far as the original intention was), any exception thrown from initResourcesIfNecessary ends up in handleListenerSetupFailure anyway... So the handleListenerSetupFailure revision should already cover those. The only difference that I can see is that your JMSException wrapper would get exposed to a specific ExceptionListener as well (when configured through the "exceptionListener" property). There shouldn't be a difference beyond that, in particular not in terms of logging...

BTW, I had to fine-tune this quite a bit in order to not end up as repetitive message on providers that do include the linked exception message in their original JMSException message already. This is for example the case with ActiveMQ. We're now checking whether the original JMSException message already contains the linked exception message in the first place, and only append the latter explicitly when not contained already (like when running against MQSeries).

Juergen


Juergen Hoeller added a comment - 17/Jul/08 02:48 AM

I've added this to CVS HEAD as discussed above; to be available in the next 2.5.6 snapshot (http://static.springframework.org/downloads/nightly/snapshot-download.php?project=SPR). Please give that implementation a try and let me know about any gaps...

Juergen