Retry is not working in spring-AMQPwith Rabbitmq - spring

am trying to retry 3 times if any exception comes while consuming message from rabbitmq,but it is not stopping after 3 times,contineously retrying n number of times.
can anybody help me on this please
thanks in advance
Config.xml
<!-- Provides connection to the RabbitMQ broker -->
<bean id="connectionFactoryRabbit"
class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory"
p:username="guest" p:password="guest" p:port="5672">
<constructor-arg value="localhost" />
</bean>
<bean id="rabbitTemplate" class="org.springframework.amqp.rabbit.core.RabbitTemplate"
p:connectionFactory-ref="connectionFactoryRabbit">
</bean>
<bean id="messageConverter"
class="org.springframework.amqp.support.converter.SimpleMessageConverter">
<property name="createMessageIds" value="true" />
</bean>
<!-- A template for sending messages and performing other commands to RabbitMQ -->
<bean
class="org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer"
p:connectionFactory-ref="connectionFactoryRabbit" p:queueNames="TEST"
p:messageListener-ref="messageListener">
<!-- <property name="txSize" value="3" /> -->
<property name="prefetchCount" value="100" />
<property name="messageListener" ref="messageListenerAdapter" />
<property name="adviceChain" ref="retryChain" />
<!-- <property name="adviceChain" ref="retryInterceptor"></property> -->
</bean>
<!-- <rabbit:queue id="adt" name="TEST" /> <rabbit:queue id="adt"> <rabbit:queue-arguments>
<entry key="x-dead-letter-queue" value="dead" /> </rabbit:queue-arguments>
</rabbit:queue> <rabbit:direct-queue name="dead"> <rabbit:bindings> <rabbit:binding
queue="dead" key="dead" /> </rabbit:bindings> </rabbit:direct-queue> -->
<util:list id="retryChain">
<bean class="org.springframework.amqp.rabbit.retry.MissingMessageIdAdvice">
<constructor-arg>
<bean class="org.springframework.retry.policy.MapRetryContextCache" />
</constructor-arg>
</bean>
<ref bean="retryInterceptor" />
</util:list>
<bean id="retryInterceptor"
class="org.springframework.amqp.rabbit.config.StatelessRetryOperationsInterceptorFactoryBean">
<property name="messageRecoverer" ref="rejectAndDontRequeueRecoverer" />
<property name="retryOperations" ref="retryTemplate" />
</bean>
<bean id="messageListenerAdapter"
class="org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter">
<property name="delegate" ref="writeToFileHandler" />
<property name="messageConverter" ref="messageConverter" />
</bean>
<bean id="writeToFileHandler" class="com.gnax.sola.jms.AmqpConsumer">
</bean>
<bean id="rejectAndDontRequeueRecoverer"
class="org.springframework.amqp.rabbit.retry.RejectAndDontRequeueRecoverer" />
<!-- <bean id="missingMessageId" class="org.springframework.amqp.rabbit.retry.MissingMessageIdAdvice"
/> -->
<bean id="retryTemplate" class="org.springframework.retry.support.RetryTemplate">
<property name="backOffPolicy">
<bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
<property name="initialInterval" value="500" />
<property name="multiplier" value="2" />
<property name="maxInterval" value="30000" />
</bean>
</property>
<property name="retryPolicy">
<bean class="org.springframework.retry.policy.SimpleRetryPolicy">
<property name="maxAttempts" value="3" />
</bean>
</property>
</bean>
<bean id="messageListener" class="com.test.amqp.AmqpConsumer" />
<!-- This helps in configuring the AMQP broker, like creating a new queue -->
<bean id="amqpAdmin" class="org.springframework.amqp.rabbit.core.RabbitAdmin">
<constructor-arg ref="connectionFactoryRabbit" />
</bean>
consumer code
public void onMessage ( Message message, Channel channel ) throws Exception
{
try
{
if ( message != null && message.getMessageProperties ().getReceivedRoutingKey () != null )
{
system.out.println(message);
}
}
catch ( Exception e )
{
LOGGER.error ( "Error while consuming the message ", e );
channel.basicNack ( message.getMessageProperties ().getDeliveryTag (), true, true );
}
}
debug log
at [Source: java.io.StringReader#d998aa1; line: 1, column: 15]
11:42:41,228 INFO [com.gnax.sola.jms.AmqpConsumer] (SimpleAsyncTaskExecutor-5) Proccessed the message from AMQP
11:42:41,448 INFO [com.gnax.sola.imagemanager.jms.ADTRequestHandler] (SimpleAsyncTaskExecutor-5) Consuming ADT Message
11:42:41,448 INFO [com.gnax.sola.imagemanager.jms.ADTRequestHandler] (SimpleAsyncTaskExecutor-5) Error while receiving ADT Message
11:42:41,448 ERROR [com.gnax.sola.imagemanager.jms.ADTRequestHandler] (SimpleAsyncTaskExecutor-5) Unrecognized token 'fgffgfd': was expecting
at [Source: java.io.StringReader#2f852217; line: 1, column: 15]
11:42:41,448 INFO [com.gnax.sola.jms.AmqpConsumer] (SimpleAsyncTaskExecutor-5) Proccessed the message from AMQP
11:42:41,448 WARN [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-5) Consumer raised exception, processing can restart if the connection factory supports it. Exception summary: com.rabbitmq.client.ShutdownSignalException: channel error; reason: {#method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - unknown delivery tag 1, class-id=60, method-id=80), null, ""}
11:42:41,448 INFO [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-5) Restarting Consumer: tag=[amq.ctag-t5CTaRT9UXy_jsmt5Bz95w], channel=Cached Rabbit Channel: AMQChannel(amqp://sola#192.168.7.108:5672/,16), acknowledgeMode=AUTO local queue size=0
11:42:41,672 INFO [com.gnax.sola.imagemanager.jms.ADTRequestHandler] (SimpleAsyncTaskExecutor-6) Consuming ADT Message
11:42:41,672 INFO [com.gnax.sola.imagemanager.jms.ADTRequestHandler] (SimpleAsyncTaskExecutor-6) Error while receiving ADT Message
11:42:41,672 ERROR [com.gnax.sola.imagemanager.jms.ADTRequestHandler] (SimpleAsyncTaskExecutor-6) Unrecognized token 'fgffgfd': was expecting
at [Source: java.io.StringReader#1736e037; line: 1, column: 15]
11:42:41,682 INFO [com.gnax.sola.jms.AmqpConsumer] (SimpleAsyncTaskExecutor-6) Proccessed the message from AMQP
11:42:41,922 INFO [com.gnax.sola.imagemanager.jms.ADTRequestHandler] (SimpleAsyncTaskExecutor-6) Consuming ADT Message
11:42:41,922 INFO [com.gnax.sola.imagemanager.jms.ADTRequestHandler] (SimpleAsyncTaskExecutor-6) Error while receiving ADT Message
11:42:41,922 ERROR [com.gnax.sola.imagemanager.jms.ADTRequestHandler] (SimpleAsyncTaskExecutor-6) Unrecognized token 'fgffgfd': was expecting
at [Source: java.io.StringReader#467b09b7; line: 1, column: 15]
11:42:41,932 INFO [com.gnax.sola.jms.AmqpConsumer] (SimpleAsyncTaskExecutor-6) Proccessed the message from AMQP
11:42:41,932 WARN [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-6) Consumer raised exception, processing can restart if the connection factory supports it. Exception summary: com.rabbitmq.client.ShutdownSignalException: channel error; reason: {#method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - unknown delivery tag 1, class-id=60, method-id=80), null, ""}
11:42:41,932 INFO [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-6) Restarting Consumer: tag=[amq.ctag-A3tGkE4oDLM0D4Lgz_4iOw], channel=Cached Rabbit Channel: AMQChannel(amqp://sola#192.168.7.108:5672/,17), acknowledgeMode=AUTO local queue size=0
11:42:41,972 WARN [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-1) Consumer raised exception, processing can restart if the connection factory supports it. Exception summary: com.rabbitmq.client.ShutdownSignalException: connection error; reason: com.rabbitmq.client.impl.UnknownChannelException: Unknown channel number 17
11:42:41,972 INFO [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-1) Restarting Consumer: tag=[amq.ctag-uczR-I6V7HeiZnQQj3PGqw], channel=Cached Rabbit Channel: AMQChannel(amqp://sola#192.168.7.108:5672/,6), acknowledgeMode=AUTO local queue size=0
11:42:41,972 WARN [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-1) Consumer raised exception, processing can restart if the connection factory supports it. Exception summary: com.rabbitmq.client.ShutdownSignalException: connection error; reason: com.rabbitmq.client.impl.UnknownChannelException: Unknown channel number 17
11:42:41,972 WARN [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-1) Consumer raised exception, processing can restart if the connection factory supports it. Exception summary: com.rabbitmq.client.ShutdownSignalException: connection error; reason: com.rabbitmq.client.impl.UnknownChannelException: Unknown channel number 17
11:42:41,972 INFO [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-1) Restarting Consumer: tag=[amq.ctag-w45jv1s-vMEVL7LHF4C1wA], channel=Cached Rabbit Channel: AMQChannel(amqp://sola#192.168.7.108:5672/,10), acknowledgeMode=AUTO local queue size=0
11:42:41,972 INFO [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-1) Restarting Consumer: tag=[amq.ctag-sacFJPkjSwD8GNmpB3rW-Q], channel=Cached Rabbit Channel: AMQChannel(amqp://sola#192.168.7.108:5672/,4), acknowledgeMode=AUTO local queue size=0
11:42:41,972 WARN [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-1) Consumer raised exception, processing can restart if the connection factory supports it. Exception summary: com.rabbitmq.client.ShutdownSignalException: connection error; reason: com.rabbitmq.client.impl.UnknownChannelException: Unknown channel number 17
11:42:41,972 INFO [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-1) Restarting Consumer: tag=[amq.ctag-d6ezJG0sAGFOJeBOKiCaaA], channel=Cached Rabbit Channel: AMQChannel(amqp://sola#192.168.7.108:5672/,2), acknowledgeMode=AUTO local queue size=0
11:42:42,032 WARN [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-1) Consumer raised exception, processing can restart if the connection factory supports it. Exception summary: com.rabbitmq.client.ShutdownSignalException: connection error; reason: com.rabbitmq.client.impl.UnknownChannelException: Unknown channel number 17
11:42:42,032 INFO [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-1) Restarting Consumer: tag=[amq.ctag--GGgfZWMvUud7Q3kE7FqtA], channel=Cached Rabbit Channel: AMQChannel(amqp://sola#192.168.7.108:5672/,9), acknowledgeMode=AUTO local queue size=0
11:42:42,032 WARN [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-1) Consumer raised exception, processing can restart if the connection factory supports it. Exception summary: com.rabbitmq.client.ShutdownSignalException: connection error; reason: com.rabbitmq.client.impl.UnknownChannelException: Unknown channel number 17
11:42:42,032 INFO [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-1) Restarting Consumer: tag=[amq.ctag-i4SmHrGYjAxvAV_uO1hDYA], channel=Cached Rabbit Channel: AMQChannel(amqp://sola#192.168.7.108:5672/,8), acknowledgeMode=AUTO local queue size=0
11:42:42,042 WARN [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-1) Consumer raised exception, processing can restart if the connection factory supports it. Exception summary: com.rabbitmq.client.ShutdownSignalException: connection error; reason: com.rabbitmq.client.impl.UnknownChannelException: Unknown channel number 17
11:42:42,042 INFO [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-1) Restarting Consumer: tag=[amq.ctag-2VPna8pwyxZHBg-Zh5OicQ], channel=Cached Rabbit Channel: AMQChannel(amqp://sola#192.168.7.108:5672/,5), acknowledgeMode=AUTO local queue size=0
11:42:42,042 WARN [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-1) Consumer raised exception, processing can restart if the connection factory supports it. Exception summary: com.rabbitmq.client.ShutdownSignalException: connection error; reason: com.rabbitmq.client.impl.UnknownChannelException: Unknown channel number 17
11:42:42,042 INFO [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-1) Restarting Consumer: tag=[amq.ctag-h1TLZWU9wI3DFBIu0k3fQA], channel=Cached Rabbit Channel: AMQChannel(amqp://sola#192.168.7.108:5672/,3), acknowledgeMode=AUTO local queue size=0
11:42:42,162 INFO [com.gnax.sola.imagemanager.jms.ADTRequestHandler] (SimpleAsyncTaskExecutor-7) Consuming ADT Message
11:42:42,162 INFO [com.gnax.sola.imagemanager.jms.ADTRequestHandler] (SimpleAsyncTaskExecutor-7) Error while receiving ADT Message
11:42:42,162 ERROR [com.gnax.sola.imagemanager.jms.ADTRequestHandler] (SimpleAsyncTaskExecutor-7) Unrecognized token 'fgffgfd': was expecting
at [Source: java.io.StringReader#1bbecd4d; line: 1, column: 15]
11:42:42,162 INFO [com.gnax.sola.jms.AmqpConsumer] (SimpleAsyncTaskExecutor-7) Proccessed the message from AMQP
11:42:42,682 WARN [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-1) Consumer raised exception, processing can restart if the connection factory supports it. Exception summary: com.rabbitmq.client.ShutdownSignalException: connection error; reason: com.rabbitmq.client.impl.UnknownChannelException: Unknown channel number 17
11:42:42,683 INFO [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-1) Restarting Consumer: tag=[amq.ctag-6lQWkrIIeM1etGSo8wcf6g], channel=Cached Rabbit Channel: AMQChannel(amqp://sola#192.168.7.108:5672/,7), acknowledgeMode=AUTO local queue size=0
11:42:43,181 WARN [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-7) Consumer raised exception, processing can restart if the connection factory supports it. Exception summary: com.rabbitmq.client.ShutdownSignalException: channel error; reason: {#method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - unknown delivery tag 1, class-id=60, method-id=80), null, ""}
11:42:43,181 INFO [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer] (SimpleAsyncTaskExecutor-7) Restarting Consumer: tag=[amq.ctag-QNs_wFdj_MjVeX768J1udg], channel=Cached Rabbit Channel: AMQChannel(amqp://sola#192.168.7.108:5672/,2), acknowledgeMode=AUTO local queue size=0

Turn on DEBUG logging to see the retry activity; if you still can't figure it out, post the log.

Related

Camel Spring remoting with Artemis Proton/Qpid client - hangs sending message

When i use the Camel spring remoting configuration to send some message, both the producer and consumer are running in different JVM.
using Apache artemis 2.14.0 version
version of camel (2.20.0), qpid (0.54.0), pooled-jms (1.1.1)
i was using the LoadMessageSupport class to push message, i see the camel routes are invoked and below debug log message.
I noticed a producer session enabled in the Artemis console.
Any clue, how to debug this or what might cause this issue.
There were some netty related debug errors which i safely ignored.
...
DEBUG [main] (DefaultManagementAgent.java:470) - Registered MBean with ObjectName: org.apache.camel:context=camel,type=components,name="bean"
DEBUG [main] (DefaultComponent.java:266) - Cannot resolve property placeholders on component: org.apache.camel.component.bean.BeanComponent#cda0432 as PropertiesComponent is not in use
DEBUG [main] (AbstractAutowireCapableBeanFactory.java:448) - Creating instance of bean 'org.apache.camel.component.jackson.converter.JacksonTypeConverters'
DEBUG [main] (AbstractAutowireCapableBeanFactory.java:484) - Finished creating instance of bean 'org.apache.camel.component.jackson.converter.JacksonTypeConverters'
INFO [main] (CamelLogger.java:159) - ID-local-vm-1624040900482-0-1 >>> (processMessage) from(direct://proxy-msg-handler) --> log[Log message on incoming message with body] <<< Pattern:InOnly, Headers:{breadcrumbId=ID-local-vm-1624040900482-0-1}, BodyType:org.apache.camel.component.bean.BeanInvocation, Body:BeanInvocation public abstract void com.myexample.MessageHandler.processMessage(com.myexample.MessageType,java.lang.String) with [ITEM_DESCRIPTION, {"info": " my name"}]]
DEBUG [main] (CamelLogger.java:153) - Log message on incoming message with body
INFO [main] (CamelLogger.java:159) - ID-local-vm-1624040900482-0-1 >>> (SubmitNotificationEvent) log[Log message on incoming message with body] --> amqpcomponent://queue:message.queue <<< Pattern:InOnly, Headers:{breadcrumbId=ID-local-vm-1624040900482-0-1}, BodyType:org.apache.camel.component.bean.BeanInvocation, Body:BeanInvocation public abstract void com.myexample.MessageHandler.processMessage(com.myexample.MessageType,java.lang.String) with [ITEM_DESCRIPTION, {"info": " my name"}]]
DEBUG [main] (SendProcessor.java:147) - >>>> service-event-queue://queue:message.queue Exchange[ID-local-vm-1624040900482-0-1]
DEBUG [main] (InternalLoggerFactory.java:45) - Using SLF4J as the default logging framework
...
DEBUG [AmqpProvider :(1):[amqp://localhost:5672]] (AmqpConnectionBuilder.java:84) - AmqpConnection { ID:6d0c8673-6a92-401d-a239-12ec696fc9d3:1 } is now open:
INFO [AmqpProvider :(1):[amqp://localhost:5672]] (JmsConnection.java:1339) - Connection ID:6d0c8673-6a92-401d-a239-12ec696fc9d3:1 connected to server: amqp://localhost:5672
DEBUG [main] (JmsTemplate.java:492) - Executing callback on JMS Session: JmsPoolSession { org.apache.qpid.jms.JmsSession#7fd26ad8 }
DEBUG [AmqpProvider :(1):[amqp://localhost:5672]] (AmqpProducerBuilder.java:68) - Creating AmqpFixedProducer for: null
DEBUG [main] (JmsConfiguration.java:622) - Sending JMS message to: message.queue with message: JmsObjectMessageFacade
After enabling the TRACE level Logs, noticed below msg
DEBUG [main] (JmsConfiguration.java:622) - Sending JMS message to: message.queue with message: JmsObjectMessageFacade { org.apache.qpid.jms.provider.amqp.message.AmqpJmsObjectMessageFacade#36cc9385 }
TRACE [AmqpProvider :(1):[amqp://localhost:5672]] (AmqpFixedProducer.java:100) - Holding Message send until credit is available.
TRACE [AmqpProvider :(1):[amqp://localhost:5672]] (AmqpProvider.java:1625) - IdleTimeoutCheck rescheduling with delay: 15000
TRACE [AmqpProvider :(1):[amqp://localhost:5672]] (NettyTcpTransport.java:560) - New incoming data read: PooledUnsafeDirectByteBuf(ridx: 0, widx: 8, cap: 65536)
TRACE [AmqpProvider :(1):[amqp://localhost:5672]] (AmqpProtocolTracer.java:49) - [1673389762:0] RECV: Empty Frame
TRACE [AmqpProvider :(1):[amqp://localhost:5672]] (AmqpProtocolTracer.java:54) - [1673389762:0] SENT: Empty Frame
TRACE [AmqpProvider :(1):[amqp://localhost:5672]] (NettyTcpTransport.java:259) - Attempted write of buffer: PooledUnsafeDirectByteBuf(ridx: 0, widx: 8, cap: 8/8)
TRACE [AmqpProvider :(1):[amqp://localhost:5672]] (NettyTcpTransport.java:273) - Attempted flush of pending writes
TRACE [AmqpProvider :(1):[amqp://localhost:5672]] (AmqpProvider.java:1625) - IdleTimeoutCheck rescheduling with delay: 15000
TRACE [AmqpProvider :(1):[amqp://localhost:5672]] (NettyTcpTransport.java:560) - New incoming data read: PooledUnsafeDirectByteBuf(ridx: 0, widx: 8, cap: 65536)
TRACE [AmqpProvider :(1):[amqp://localhost:5672]] (AmqpProtocolTracer.java:49) - [1673389762:0] RECV: Empty Frame
TRACE [AmqpProvider :(1):[amqp://localhost:5672]] (AmqpProtocolTracer.java:54) - [1673389762:0] SENT: Empty Frame
TRACE [AmqpProvider :(1):[amqp://localhost:5672]] (NettyTcpTransport.java:259) - Attempted write of buffer: PooledUnsafeDirectByteBuf(ridx: 0, widx: 8, cap: 8/8)
TRACE [AmqpProvider :(1):[amqp://localhost:5672]] (NettyTcpTransport.java:273) - Attempted flush of pending writes
TRACE [AmqpProvider :(1):[amqp://localhost:5672]] (AmqpProvider.java:1625) - IdleTimeoutCheck rescheduling with delay: 15000
Below is the context xml which i used to send message from java class.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/spring"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd
http://www.springframework.org/schema/util ttp://www.springframework.org/schema/util/spring-util.xsd">
<bean id="jmsConnectionFactory" class="org.apache.qpid.jms.JmsConnectionFactory">
<property name="remoteURI" value="amqp://localhost:5672?amqp.traceFrames=true"/>
</bean>
<bean id="jpcf" class="org.messaginghub.pooled.jms.JmsPoolConnectionFactory" init-method="start" destroy-method="stop" >
<property name="maxConnections" value="3" />
<property name="connectionFactory" ref="jmsConnectionFactory" />
</bean>
<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="jpcf" />
<property name="concurrentConsumers" value="3" />
</bean>
<bean id="amqpcomponent" class="org.apache.camel.component.amqp.AMQPComponent">
<property name="configuration" ref="jmsConfig" />
</bean>
<!-- Camel Spring Remoting Interface -->
<camel:proxy id="proxyObject" binding="false" serviceUrl="direct:proxy-msg-handler" serviceInterface="com.myexample.MessageHandler"/>
<!-- Bean that initialize the Spring Remoting for handling message -->
<bean id="BeanProxy" class="com.myexample.MessageProducer">
<property name="messageHandler" ref="proxyObject"/>
</bean>
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring" autoStartup="true" trace="true">
<camel:route autoStartup="true" id="processMessage">
<camel:from uri="direct:proxy-msg-handler"/>
<camel:log message="Log incoming message" logName="Incoming" loggingLevel="DEBUG"/>
<camel:inOnly uri="amqpcomponent:queue:message.queue"/>
</camel:route>
</camelContext>
</beans>
java class running the context, used to invoke the remote spring bean method.
Using below java class to push message to Artemis queue
package com.myexample;
public class LoadMessageSupport {
public static void main(String ...strings) {
ApplicationContext appContext =null;
try {
appContext = new ClassPathXmlApplicationContext("file:/paht/to/context/message-handler-context.xml");
MessageProducer messageProducer = appContext.getBean(MessageProducer.class);
message = "{ \"itemDesc\" : \"test description\" }" ;
System.out.println(message);
messageProducer.sendMessage(MessageType.ITEM_DESC, message);
// enum messagetype already defined within project
//System.exit(0);
}catch(Exception exe) {
System.out.println("Something wrong... ");
exe.printStackTrace();
}finally {
if(camelContext!=null) {
System.out.println("camel context stopped...");
camelContext.stop();
}
}
}
}
message receiver class
#InOnly
public interface MessageHandler{
public processMessage(MessageType type, Order order);
public processMessage(MessageType type, String message); // trying to invoke this message
}
producer class
public class MessageProducer{
​// using the proxy object within the producer object
​// this will invoke the spring bean using remote (rmi)
​private MessageHandler messageHandler;
protected MessageHandler getMessageHandler() {
return this.messageHandler;
}
public void setMessageHandler(MessageHandler messageHandler) {
this.messageHandler = messageHandler;
}
//constructor
public ​MessageProducer() {}
​
public void sendMessage(MessageType type, Order order ){
​getMessageHandler().processMessage(type,order);
​}
​public void sendMessage(MessageType type, String message ){
​getMessageHandler().processMessage(type,message);
​}
message Receiver
public class MessageReceiver implements MessageHandler {
#Handler
public void processMessage(MessageType type, Order order){
System.out.println(" received type and ORDER info ...");
// invoke methods for logical processing
}
#Handler
public void processMessage(MessageType type, String message){
System.out.println(" received type and MESSAGE info for procesing...");
// invoke methods for logical processing
}
}
When i was trying earlier, seems like my VM didn't have sufficient memory.
free -h indicate only 500MB left out.
After restarting the VM the message is now sent to Artemis borker.

Azure Service Bus : Amqp Idle Timeout condition = amqp:link:detach-forced

The error I get:
2019-12-09 06:39:33.189 ERROR 107132 --- [http-nio-8082-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.jms.IllegalStateException: The MessageProducer was closed due to an unrecoverable error.; nested exception is javax.jms.IllegalStateException: The MessageProducer was closed due to an unrecoverable error.] with root cause
javax.jms.JMSException: Idle link tracker, link qpid-jms:sender:ID:7300953e-f587-4ae3-b9fe-85b84e032554:1:101:1:order-update has been idle for 1800000ms TrackingId:801ab247-3f36-4470-8665-08846eb1c181_G24, SystemTracker:client-link34404815, Timestamp:2019-12-06T21:04:35 [condition = amqp:link:detach-forced]
at org.apache.qpid.jms.provider.amqp.AmqpSupport.convertToException(AmqpSupport.java:164)
at org.apache.qpid.jms.provider.amqp.AmqpSupport.convertToException(AmqpSupport.java:117)
at org.apache.qpid.jms.provider.amqp.AmqpAbstractResource.processRemoteClose(AmqpAbstractResource.java:262)
at org.apache.qpid.jms.provider.amqp.AmqpProvider.processUpdates(AmqpProvider.java:906)
at org.apache.qpid.jms.provider.amqp.AmqpProvider.access$1800(AmqpProvider.java:102)
at org.apache.qpid.jms.provider.amqp.AmqpProvider$17.run(AmqpProvider.java:792)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:748)
dependencies
compile group: 'com.microsoft.azure', name: 'azure-servicebus-spring-boot-starter', version: '0.2.0'
compile group: 'javax.jms', name: 'javax.jms-api', version: '2.0.1'
compile group: 'org.apache.qpid', name: 'qpid-jms-client', version: '0.28.0'
compile group: 'org.apache.camel', name: 'camel-jms', version: '2.24.1'
compile group: 'org.springframework.integration', name: 'spring-integration-jms', version: '5.0.4.RELEASE'
jmsConnectionFactory configuration:
<bean id="jmsConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory">
<bean class="org.apache.qpid.jms.JmsConnectionFactory">
<constructor-arg value="${azure.jms.url}" />
<property name="username" value="${azure.jms.username}" />
<property name="password" value="${azure.jms.password}" />
<property name="clientID" value="AltaPay" />
<property name="receiveLocalOnly" value="true" />
<property name="localMessageExpiry" value="true" />
<property name="populateJMSXUserID" value="true" />
</bean>
</property>
<property name="exceptionListener">
<bean class="com.lauraashley.microservice.altapay.callback.exception.CustomJMSExceptionListener" />
</property>
<property name="sessionCacheSize" value="10" />
<property name="cacheConsumers" value="false" />
</bean>
<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="jmsConnectionFactory" />
<property name="cacheLevelName" value="CACHE_NONE" />
</bean>
CustomJMSExceptionListener
public class CustomJMSExceptionListener implements ExceptionListener {
private static final Logger logger = getLogger(CustomJMSExceptionListener.class);
#Override
public void onException(JMSException exception) {
// TODO Auto-generated method stub
logger.error("--------------- Catched exception with CustomJMSExceptionListener ---------------");
logger.error("Error code:"+exception.getErrorCode());
logger.error("Msg:"+exception.getMessage());
exception.printStackTrace();
logger.error("---------------------------------------------------------------------------------");
}
}
How I reproduce it
First: the CustomJMSExceptionListener is not used, isn't configured ok?
The application is a eccomerce app on OCC ( oracle cloud commerce ) platform that used java spring-boot services for the payment integration and flow.
This error occurs when an order exceeds the idle time then the connection with the Azure Service Bus fails and in order to reconnect I must restart the java app, and this is quite a big problem because no more orders can be processed. I read that CachingConnectionFactory has reconnectOnException which by default is true.
I don't really understand why this happens and what is the solution in order to fix it.
The exception is indicating that Azure has closed the producer because it was idle for to long, meaning it hadn't sent a message within the timeout (some documentation here). You might be able to work around this when using the CachingConnectionFactory by configuring the cache producers option to false so that producers are created on demand but I'm not entirely sure on that as I don't have any way to test it.
This isn't a Qpid JMS client level bug but rather the behaviour of Azure kicking in where after I think it's ten minutes of no activity on a link it will forcibly close the link. In a non-spring based application you'd have to account for this by catching the JMSException on send either attempting to create a new producer and sending again or by tearing down the whole connection and starting over. Your reaction somewhat depends on foreknowledge that you are using Azure and knowing that this can happen.
As answered above this is an expected behavior from Azure Service Bus, This issue is open in azure-spring-boot. As of now the workaround is to set the CachingConnectionFactory.cacheProducers value to False, so new Producer will be created for every session.
CachingConnectionFactory connectionFactory = (CachingConnectionFactory) jmsTemplate.getConnectionFactory();
connectionFactory.setCacheProducers(false);
Another possible way of doing this,
#Bean
public ConnectionFactory jmsConnectionFactory(AzureServiceBusJMSProperties busJMSProperties){
final String connectionString = busJMSProperties.getConnectionString();
final String clientId = busJMSProperties.getTopicClientId();
final int idleTimeout = busJMSProperties.getIdleTimeout();
final ServiceBusKey serviceBusKey = ConnectionStringResolver.getServiceBusKey(connectionString);
final String remoteUri = String.format("amqps://%s?amqp.idleTimeout=%d&amqp.traceFrames=true",
serviceBusKey.getHost(), idleTimeout);
final JmsConnectionFactory jmsConnectionFactory =
new JmsConnectionFactory(
serviceBusKey.getSharedAccessKeyName(),
serviceBusKey.getSharedAccessKey(),
remoteUri
);
jmsConnectionFactory.setClientID(clientId);
CachingConnectionFactory cachingConnectionFactory =
new CachingConnectionFactory(jmsConnectionFactory);
// set cache producers to FALSE here
cachingConnectionFactory.setCacheProducers(false);
return cachingConnectionFactory;
}

Spring singleton scope isn't working in spring-integration application

I have a spring-integration application with the following configuration :
<beans:bean id="customMessageListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer" scope = "singleton">
<beans:property name="errorHandler" ref="customErrorHandler"/>
<beans:property name="connectionFactory" ref="connectionFactory" />
<beans:property name="destination" ref="jmsInputQueueXssl" />
<beans:property name="sessionTransacted" value="true" />
<beans:property name="maxConcurrentConsumers" value="1" />
<beans:property name="concurrentConsumers" value="1" />
<beans:property name="receiveTimeout" value="5000" />
<beans:property name="recoveryInterval" value="60000" />
<beans:property name="autoStartup" value="true" />
<beans:property name="exposeListenerSession" value="false" />
<beans:property name="subscriptionDurable" value="true" />
<beans:property name="durableSubscriptionName" value="${ibm.jms.subscription.id1}" />
<beans:property name="backOff" ref="myBackoff" />
</beans:bean>
<beans:bean id="myBackoff" class="c.h.i.c.d.x.j.MyFixedBackOff">
<beans:constructor-arg index="0" value="5000"/>
<beans:constructor-arg index="1" value="5"/>
</beans:bean>
<!-- Custom error handler -->
<beans:bean id="customErrorHandler" class="c.h.i.c.d.x.j.XsslCustomErrorHandler" />
<beans:beans profile="env">
<jms:message-driven-channel-adapter
id="jmsInboundAdapterXssl" channel="channel2"
acknowledge="transacted" error-channel="errorChannel"
container="customMessageListenerContainer"/>
</beans:beans>
However, it seems that there are several instances of that class customMessageListenerContainer if I read the logs :
2019-05-10 17:54:39,783 INFO [main] o.s.i.e.SourcePollingChannelAdapter [AbstractEndpoint.java:97] started org.springframework.integration.config.SourcePollingChannelAdapterFactoryBean#0
2019-05-10 17:54:39,783 INFO [main] o.s.c.s.DefaultLifecycleProcessor [DefaultLifecycleProcessor.java:341] Starting beans in phase 2147483647
2019-05-10 17:54:39,924 INFO [customMessageListenerContainer-1] c.h.i.c.d.x.j.MyFixedBackOff [MyFixedBackOff.java:115] MyFixedBackOff currentAttempts = 0
2019-05-10 17:54:44,930 WARN [customMessageListenerContainer-1] o.s.j.l.DefaultMessageListenerContainer [DefaultMessageListenerContainer.java:871] Setup of JMS message listener invoker failed for destination 'queue:///CT_XSSL.CT_CPMX.MRZC_DGRM.0013' - trying to recover. Cause: JMSWMQ2008: Failed to open MQ queue 'CT_XSSL.CT_CPMX.MRZC_DGRM.0013'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2085' ('MQRC_UNKNOWN_OBJECT_NAME').
2019-05-10 17:54:44,930 INFO [customMessageListenerContainer-1] o.s.j.l.DefaultMessageListenerContainer [DefaultMessageListenerContainer.java:921] Successfully refreshed JMS Connection
2019-05-10 17:54:44,930 INFO [customMessageListenerContainer-2] c.h.i.c.d.x.j.MyFixedBackOff [MyFixedBackOff.java:115] MyFixedBackOff currentAttempts = 0
2019-05-10 17:54:49,938 WARN [customMessageListenerContainer-2] o.s.j.l.DefaultMessageListenerContainer [DefaultMessageListenerContainer.java:871] Setup of JMS message listener invoker failed for destination 'queue:///CT_XSSL.CT_CPMX.MRZC_DGRM.0013' - trying to recover. Cause: JMSWMQ2008: Failed to open MQ queue 'CT_XSSL.CT_CPMX.MRZC_DGRM.0013'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2085' ('MQRC_UNKNOWN_OBJECT_NAME').
2019-05-10 17:54:49,938 INFO [customMessageListenerContainer-2] o.s.j.l.DefaultMessageListenerContainer [DefaultMessageListenerContainer.java:921] Successfully refreshed JMS Connection
2019-05-10 17:54:49,953 INFO [customMessageListenerContainer-3] c.h.i.c.d.x.j.MyFixedBackOff [MyFixedBackOff.java:115] MyFixedBackOff currentAttempts = 0
2019-05-10 17:54:54,962 WARN [customMessageListenerContainer-3] o.s.j.l.DefaultMessageListenerContainer [DefaultMessageListenerContainer.java:871] Setup of JMS message listener invoker failed for destination 'queue:///CT_XSSL.CT_CPMX.MRZC_DGRM.0013' - trying to recover. Cause: JMSWMQ2008: Failed to open MQ queue 'CT_XSSL.CT_CPMX.MRZC_DGRM.0013'.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2085' ('MQRC_UNKNOWN_OBJECT_NAME').
2019-05-10 17:54:54,962 INFO [customMessageListenerContainer-3] o.s.j.l.DefaultMessageListenerContainer [DefaultMessageListenerContainer.java:921] Successfully refreshed JMS Connection
How can I make customMessageListenerContainer effectively a singleton ?
What makes you think it's not a singleton?
If you mean the thread names are incrementing (customMessageListenerContainer-2 etc), it's because by default a SimpleAsyncTaskExecutor is used and a new thread is used after each failure (and the previous one terminates).
You can change the executor to a different implementation (e.g. thread pool) if you want.
Singleton is the default scope.

JmsListener does not receive message from Activemq

I have a Spring JmsListener in my code. It's receive and consume message for 2 days but suddenly after this 2 days it receive no message from external activemq. However there is some pending message in its queue. When I reset the activemq and consumer, the consumer receive large amount of message. When the messages are pending the consumer connected to the activemq(on behalf of spring actuator logs).
The logs and config show that activemq did not push message to consumer. I have another services like this consumer that receive the message from other queue. Also the second consumer has same problem. I want to know why this problem happened and how can I solve this problem.
Here is my config and log:
Consumer:
application.xml:
spring.jms.pub-sub-domain=false
spring.jms.template.delivery-mode=persistent
spring.activemq.broker-url=${BROKER_URL:failover:(tcp://activemq1:61616,tcp://activemq2:61616)?maxReconnectDelay=2500}
spring.activemq.user=${BROKER_USER:admin}
spring.activemq.password=${BROKER_PASSWORD:admin}
JmsConfiguration:
#EnableJms
#Configuration
public class JmsConfiguration {
#Bean
public JmsListenerContainerFactory<?> myFactory(ActiveMQConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
redeliveryPolicy.setMaximumRedeliveries(0);
connectionFactory.setRedeliveryPolicy(redeliveryPolicy);
factory.setMessageConverter(messageConverter());
configurer.configure(factory, connectionFactory);
return factory;
}
private MessageConverter messageConverter() {
MappingJackson2MessageConverter messageConverter = new MappingJackson2MessageConverter();
messageConverter.setTargetType(MessageType.TEXT);
messageConverter.setTypeIdPropertyName("_type");
return messageConverter;
}
}
Listener:
#Component
public class MessageReceiver {
#JmsListener(destination = Constant.OFFICE_REQUEST_QUEUE, containerFactory = "myFactory")
public void receive(RequestMessage requestMessage, #Headers Map<String,Object> headers) throws NonPersistenceServiceException {
// do someting on received message
}
}
Activemq config:
activemq.xml:
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>file:${activemq.conf}/credentials.properties</value>
</property>
</bean>
<bean id="logQuery" class="io.fabric8.insight.log.log4j.Log4jLogQuery"
lazy-init="false" scope="singleton"
init-method="start" destroy-method="stop">
</bean>
<bean id="oracleDS" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close">
<property name="URL" value="jdbc:oracle:thin:#(DESCRIPTION= (SDU=32768)(ADDRESS=(PROTOCOL=TCP)(HOST= dms-db1-vip)(PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST= dms-db2-vip)(PORT=1521)) (LOAD_BALANCE=yes)(FAILOVER=ON)(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=orcl)(failover_mode=(type=select)(method=basic)(retries=5)(delay=1))))"/>
<property name="user" value="ora_user"/>
<property name="password" value="ora_pass"/>
</bean>
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" >
<plugins>
<redeliveryPlugin fallbackToDeadLetter="true"
sendToDlqIfMaxRetriesExceeded="true">
<redeliveryPolicyMap>
<redeliveryPolicyMap>
<defaultEntry>
<redeliveryPolicy
useExponentialBackOff="true"
backOffMultiplier="2"
maximumRedeliveryDelay="1200000"
maximumRedeliveries="82"/>
</defaultEntry>
</redeliveryPolicyMap>
</redeliveryPolicyMap>
</redeliveryPlugin>
</plugins>
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry queue=">">
<deadLetterStrategy>
<individualDeadLetterStrategy queuePrefix="DLQ." useQueueForQueueMessages="true"/>
</deadLetterStrategy>
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>
<managementContext>
<managementContext createConnector="false"/>
</managementContext>
<persistenceAdapter>
<jdbcPersistenceAdapter dataSource="#oracleDS" />
</persistenceAdapter>
<systemUsage>
<systemUsage>
<memoryUsage>
<memoryUsage percentOfJvmHeap="70" />
</memoryUsage>
<storeUsage>
<storeUsage limit="100 gb"/>
</storeUsage>
<tempUsage>
<tempUsage limit="50 gb"/>
</tempUsage>
</systemUsage>
</systemUsage>
<transportConnectors>
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
</transportConnectors>
<shutdownHooks>
<bean xmlns="http://www.springframework.org/schema/beans" class="org.apache.activemq.hooks.SpringContextHook" />
</shutdownHooks>
</broker>
<import resource="jetty.xml"/>
</beans>
Below is The log of actuator in consumer:
{"log":"20:20:26.775 ### [ActiveMQ Task-1] INFO o.a.activemq.transport.failover.FailoverTransport ### ### ###\r\n","stream":"stdout"}
{"log":" Successfully connected to tcp://activemq1:61616\r\n","stream":"stdout"}
{"log":"20:20:36.638 ### [ActiveMQ Task-1] INFO o.a.activemq.transport.failover.FailoverTransport ### ### ###\r\n","stream":"stdout"}
{"log":" Successfully connected to tcp://activemq1:61616\r\n","stream":"stdout"}
{"log":"20:20:36.779 ### [ActiveMQ Task-1] INFO o.a.activemq.transport.failover.FailoverTransport ### ### ###\r\n","stream":"stdout"}
{"log":" Successfully connected to tcp://activemq1:61616\r\n","stream":"stdout"}
{"log":"20:20:46.464 ### [ActiveMQ Task-1] INFO o.a.activemq.transport.failover.FailoverTransport ### ### ###\r\n","stream":"stdout"}
{"log":" Successfully connected to tcp://activemq1:61616\r\n","stream":"stdout"}
{"log":"20:20:46.774 ### [ActiveMQ Task-1] INFO o.a.activemq.transport.failover.FailoverTransport ### ### ###\r\n","stream":"stdout"}
Activemq erros log:
2019-03-05 20:19:55,448 | WARN | Transport Connection to: tcp://10.42.1.0:63493 failed: java.io.IOException: Frame size of 1 GB larger than max allowed 100 MB | org.apache.activemq.broker.TransportConnection.Transport | ActiveMQ Transport: tcp:///10.42.1.0:63493#61616
2019-03-05 20:20:05,776 | WARN | Transport Connection to: tcp://10.42.1.0:63498 failed: java.io.EOFException | org.apache.activemq.broker.TransportConnection.Transport | ActiveMQ Transport: tcp:///10.42.1.0:63498#61616
2019-03-05 20:20:05,776 | WARN | Transport Connection to: tcp://10.42.1.0:63497 failed: java.io.EOFException | org.apache.activemq.broker.TransportConnection.Transport | ActiveMQ Transport: tcp:///10.42.1.0:63497#61616
Such scenarios are most often the result of one of two issues:
Some network component (router, firewall) silently closes a socket due to inactivity without notifying the client or server so, unless heartbeats are enabled, the connection is dead.
The consumer thread is somehow "stuck" in user code so it stops receiving new messages; take a stack dump to see what the container threads are doing.

FailoverTransport instantiated multiple times

I'm using spring-jms version 3.0.5 and activeMQ version 4.5.2. When deployed to Tomcat, everything seems to work properly. When deployed to WebSphere, it appears that four separate failover transports are being insantiated, and my MessageListener implementation receives the same message four times for every message that gets published to my topic.
Here's my config:
<bean id="activeMQConnectionFactory"
class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="failover://(tcp://server.com:12345,tcp://server2.com:12345)?randomize=false/>
</bean>
<bean id="topic" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="TOPIC.ONE" />
</bean>
<bean id="jmsTemplate" class="org.sprinframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="defaultDestination" ref="topic" />
</bean>
<bean name="topicListener" class="com.foo.TopicListener" />
<jms:listener-container connection-factory="connectionFactory" cache="auto" destination-type="topic">
<jms:listener destination="topic" ref="topicListener" />
</jms:listener-container>
Here's my message listener:
import javax.jms.MessageListener;
import org.springframework.stereotype.Component;
#Component
public class TopicListener implements MessageListener {
public void onMessage(Message msg) {
log(msg);
}
}
And here's what I see in my logs (only on WebSphere)
11:59:59,764 () INFO (Thread-50) (DefaultLifecycleProcessor) Starting beans in phase 214783647
12:00:00,140 () INFO (ActiveMQ Task) (FailoverTransport) Successfully connected to tcp://server.com:12345
12:00:00,253 () INFO (ActiveMQ Task) (FailoverTransport) Successfully connected to tcp://server.com:12345
12:00:00,342 () INFO (ActiveMQ Task) (FailoverTransport) Successfully connected to tcp://server.com:12345
12:00:00,423 () INFO (ActiveMQ Task) (FailoverTransport) Successfully connected to tcp://server.com:12345
12:00:00,492 () INFO (Thread-50) (ContextLoader) Root WebApplicationContext: initialization completed in 100239 ms
And then once I publish to the topic, I see:
12:01:00,250 () INFO (org.springframework.jms.listener.DefaultMessageListenerContainer#0-1) (TopicListener) logging message
12:01:00,251 () INFO (org.springframework.jms.listener.DefaultMessageListenerContainer#3-1) (TopicListener) logging message
12:01:00,251 () INFO (org.springframework.jms.listener.DefaultMessageListenerContainer#2-1) (TopicListener) logging message
12:01:00,275 () INFO (org.springframework.jms.listener.DefaultMessageListenerContainer#1-1) (TopicListener) logging message
I've seen some indication that this sort of behavior might be expected if I'd set concurrentConsumers > 1, but as far as I can tell, I haven't. How can I make sure I'm only receiving these messages once?
UPDATE:
With debug logging on, I also see:
2012-10-28 12:00:00,000 () DEBUG (Thread-50) (DefaultLifecycleProcessor) Starting bean 'org.springframework.jms.listener.DefaultMessageListenerContainer#0' of type [class org.springframework.jms.listener.DefaultMessageListenerContainer]
2012-10-28 12:00:00,011 () DEBUG (Thread-50) (DefaultLifecycleProcessor) Starting bean 'org.springframework.jms.listener.DefaultMessageListenerContainer#1' of type [class org.springframework.jms.listener.DefaultMessageListenerContainer]
2012-10-28 12:00:00,021 () DEBUG (Thread-50) (DefaultLifecycleProcessor) Starting bean 'org.springframework.jms.listener.DefaultMessageListenerContainer#2' of type [class org.springframework.jms.listener.DefaultMessageListenerContainer]
2012-10-28 12:00:00,029 () DEBUG (Thread-50) (DefaultLifecycleProcessor) Starting bean 'org.springframework.jms.listener.DefaultMessageListenerContainer#3' of type [class org.springframework.jms.listener.DefaultMessageListenerContainer]
Why would Spring create four of these beans?

Resources