diff --git a/spring-integration-jms/src/main/java/org/springframework/integration/jms/JmsOutboundGateway.java b/spring-integration-jms/src/main/java/org/springframework/integration/jms/JmsOutboundGateway.java
index 38a05ac5da..1140abd2f7 100644
--- a/spring-integration-jms/src/main/java/org/springframework/integration/jms/JmsOutboundGateway.java
+++ b/spring-integration-jms/src/main/java/org/springframework/integration/jms/JmsOutboundGateway.java
@@ -142,6 +142,8 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler imp
private final Object lifeCycleMonitor = new Object();
+ private volatile boolean requiresReply;
+
/**
* Set whether message delivery should be persistent or non-persistent,
* specified as a boolean value ("true" or "false"). This will set the delivery
@@ -389,6 +391,12 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler imp
this.useReplyContainer = useReplyContainer;
}
+ @Override
+ public void setRequiresReply(boolean requiresReply) {
+ super.setRequiresReply(requiresReply);
+ this.requiresReply = requiresReply;
+ }
+
private Destination determineRequestDestination(Message> message, Session session) throws JMSException {
if (this.requestDestination != null) {
return this.requestDestination;
@@ -617,8 +625,13 @@ public class JmsOutboundGateway extends AbstractReplyProducingMessageHandler imp
jmsReply = this.sendAndReceiveWithContainer(requestMessage);
}
if (jmsReply == null) {
- throw new MessageTimeoutException(message,
- "failed to receive JMS response within timeout of: " + this.receiveTimeout + "ms");
+ if (this.requiresReply) {
+ throw new MessageTimeoutException(message,
+ "failed to receive JMS response within timeout of: " + this.receiveTimeout + "ms");
+ }
+ else {
+ return null;
+ }
}
Object result = jmsReply;
if (this.extractReplyPayload) {
diff --git a/spring-integration-jms/src/test/java/org/springframework/integration/jms/JmsOutboundInsideChainTests-context.xml b/spring-integration-jms/src/test/java/org/springframework/integration/jms/JmsOutboundInsideChainTests-context.xml
index 27c827d8a0..746624cd58 100644
--- a/spring-integration-jms/src/test/java/org/springframework/integration/jms/JmsOutboundInsideChainTests-context.xml
+++ b/spring-integration-jms/src/test/java/org/springframework/integration/jms/JmsOutboundInsideChainTests-context.xml
@@ -18,12 +18,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-jms/src/test/java/org/springframework/integration/jms/JmsOutboundInsideChainTests.java b/spring-integration-jms/src/test/java/org/springframework/integration/jms/JmsOutboundInsideChainTests.java
index 3cbe61cb31..4bb0d53f98 100644
--- a/spring-integration-jms/src/test/java/org/springframework/integration/jms/JmsOutboundInsideChainTests.java
+++ b/spring-integration-jms/src/test/java/org/springframework/integration/jms/JmsOutboundInsideChainTests.java
@@ -16,33 +16,58 @@
package org.springframework.integration.jms;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
import org.junit.Test;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.core.PollableChannel;
import org.springframework.integration.support.MessageBuilder;
-
-import static org.junit.Assert.*;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* //INT-2275
*
* @author Artem Bilan
*/
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration
public class JmsOutboundInsideChainTests {
+ @Autowired
+ private MessageChannel outboundChainChannel;
+
+ @Autowired
+ private PollableChannel receiveChannel;
+
+ @Autowired
+ private MessageChannel outboundGatewayChainChannel;
+
+ @Autowired
+ private PollableChannel repliesChannel;
+
@Test
public void testJmsOutboundChannelInsideChain(){
- ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("JmsOutboundInsideChainTests-context.xml", getClass());
- PollableChannel receiveChannel = context.getBean("receiveChannel", PollableChannel.class);
- MessageChannel outboundChainChannel = context.getBean("outboundChainChannel", MessageChannel.class);
String testString = "test";
Message shippedMessage = MessageBuilder.withPayload(testString).build();
- outboundChainChannel.send(shippedMessage);
- Message> receivedMessage = receiveChannel.receive();
+ this.outboundChainChannel.send(shippedMessage);
+ Message> receivedMessage = this.receiveChannel.receive(2000);
assertEquals(testString, receivedMessage.getPayload());
- context.close();
+ }
+
+ @Test
+ public void testJmsOutboundGatewayRequiresReply(){
+ this.outboundGatewayChainChannel.send(MessageBuilder.withPayload("test").build());
+ assertNotNull(this.repliesChannel.receive(2000));
+
+ this.outboundGatewayChainChannel.send(MessageBuilder.withPayload("test").build());
+ assertNull(this.repliesChannel.receive(2000));
}
}
diff --git a/src/reference/docbook/jms.xml b/src/reference/docbook/jms.xml
index f8b8c5169d..7eb48b5bf8 100644
--- a/src/reference/docbook/jms.xml
+++ b/src/reference/docbook/jms.xml
@@ -315,7 +315,8 @@
request-destination-expression=""]]>]]>]]>]]>]]>
@@ -497,6 +498,18 @@
This setting will only take effect if explicit-qos-enabled is true.
+
+
+ Specify whether this outbound gateway must return a non-null value. This value is
+ true by default, and a MessageTimeoutException will be thrown when
+ the underlying service does not return a value after the receive-timeout.
+ Note, it is important to keep in mind that, if the service is never expected
+ to return a reply, it would be better to use a <int-jms:outbound-channel-adapter/>
+ instead of a <int-jms:outbound-gateway/> with requires-reply="false".
+ With the latter, the sending thread is blocked, waiting for a reply for the receive-timeout
+ period.
+
+
When this element is included, replies are received by a MessageListenerContainer