|
|
error-channel for inbound-channel-adapter not working as expected
Hi,
Regarding the evolution on the quot;error-channelquot; on the inbound-channel-adapter component, even though the exception is sent on the error-channel, a MessagingException is thrown anyway back to the caller, so within a JMS transaction, the message is rollbacked and received over and over (as it will fail everytime)...
I thought that the aim of the quot;error-channelquot; was to add quot;catch-allquot; feature to avoid this kind of disagreement, wasn't it ?
See the following discussion with Mark about this subject : showthread.php?t=97699
Here is a very simple configuration to reproduce the issue:Code:
lt;int:channel id=quot;inputChannelquot; /gt;
lt;int:channel id=quot;errorChannelquot; /gt;
lt;int-jms:message-driven-channel-adapter channel=quot;inputChannelquot; container=quot;myJmsListenerquot; error-channel=quot;errorChannelquot; /gt;
lt;bean id=quot;myJmsListenerquot;gt;
lt;property name=quot;destinationNamequot; value=quot;myQueuequot; /gt;
lt;property name=quot;connectionFactoryquot; ref=quot;myConnectionFactoryquot; /gt;
lt;property name=quot;destinationResolverquot; ref=quot;myDestinationResolverquot; /gt;
lt;property name=quot;receiveTimeoutquot; value=quot;-1quot; /gt;
lt;property name=quot;sessionAcknowledgeModequot; value=quot;0quot; /gt;
lt;property name=quot;sessionTransactedquot; value=quot;truequot; /gt;
lt;/beangt;
lt;int:service-activator input-channel=quot;inputChannelquot; output-channel=quot;nullChannelquot; method=quot;throwExceptionquot;gt;
lt;bean class=quot;Servicequot; /gt;
lt;/int:service-activatorgt;
lt;int:service-activator input-channel=quot;errorChannelquot; output-channel=quot;nullChannelquot; method=quot;displayExceptionquot;gt;
lt;bean class=quot;Servicequot; /gt;
lt;/int:service-activatorgt;
Code:
public class Service {
public Message throwException(Messagelt;?gt; msg) {
throw new RuntimeException(quot;This exception is expected !quot;);
}
public void displayException(Messagelt;?gt; msg) {
System.out.println(msg);
}
}
Thank you,
Pierre
PS : Using SI 2.0 GA
[Edit: Adding class quot;Servicequot;]
Pierre
The aim for adding the error-channel was not to be a catch-all errors component, but to expose a channel to let you register a catch-all component.
For example, you may want to subscribe to an error-channel, process the ErrorMessage, create a new successful Message and return it. In this case what JMS would see is nothing but a success.
But you may also have a use case where you want to intercept an exception, do something with it and re-throw. For those scenarios you would receive an ErrorMessage on the error-channel, do something with it and return the same ErrorMessage back.
Does that explain?
The MessagingGatewaySupport class seems to throw an exception anyway, whatever is done in the error-channel. So, even though the error-channel returns a valid message, the JMS component will receive a MessagingException and rollback the transaction.
Or did I miss something?Code:
protected void send(Object object) {
(...)
try {
this.messagingTemplate.convertAndSend(this.requestChannel, object, this.historyWritingPostProcessor);
}
catch (Exception e) {
if (this.errorChannel != null) {
this.messagingTemplate.send(this.errorChannel, new ErrorMessage(e));
}
else if (e instanceof RuntimeException) {
throw (RuntimeException) e;
}
throw new MessagingException(quot;failed to send messagequot;, e);
}
}Yep, we encountered the same issues discussed in the following thread, showthread.php?t=98921 the broker redelivers the errormessage (the one created by the subscriber to the errorChannel) and this is not what we expected. We had to remove the transaction from the DMLC which is not ideal.
Pierre, James, you guys both right. We are fixing it now.
Sorry about it.
Pierre, James
It was actually a bug but the good thing is that it has been resolved browse/INT-1694 so it should be available in the next release (planned for later on today)
Thanks for reporting it! |
|