With reference to Link, I created durable Subscriber using JMS+ActiveMQ+SpringBoot. I also generated Unique client ID using UUID.randomUUID().toString(). However,while starting Subscriber(Receiver), application is throwing following warning message
Cause: Durable consumer is in use for client: 8f1019fd-50d4-457b-b417-2058917ed7bb and subscriptionName: org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter
Pleae help me to remove the above warning message.
Durable topic with client id - '8f1019fd-50d4-457b-b417-2058917ed7bb' is create in ActiveMQ server
Following is the source code
ReceiverTopicApplicaton.java
@SpringBootApplication
@EnableJms
public class ReceiverTopicApplicaton {
public static void main(String[] args) {
SpringApplication.run(ReceiverTopicApplicaton.class, args);
}
private ConnectionFactory connectionFactory() {
return new ActiveMQConnectionFactory("tcp://localhost:61616");
}
@Bean
public DefaultJmsListenerContainerFactory topicListenerFactory() {
DefaultJmsListenerContainerFactory factory =
new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory());
//we need to set destinationResolver() to remove the warning message
factory.setDestinationResolver(destinationResolver());
factory.setPubSubDomain(true);
factory.setSubscriptionDurable(true);
factory.setConcurrency("3-10");
factory.setClientId(UUID.randomUUID().toString());
factory.setSubscriptionDurable(true);
return factory;
}
Receiver.java
@Component
public class Receiver {
@JmsListener(destination = "durable.topic", containerFactory = "topicListenerFactory")
public void receiveMessage(final Message message) throws JMSException {
if (message instanceof ObjectMessage) {
Object object = ((ObjectMessage) message).getObject();
StudentDto studentDto = (StudentDto) object;
System.out.println("Receiver :: Student Object Received..." + studentDto);
}
}
}
StudentDto.java
public class StudentDto implements Serializable {
private Long studentId;
private String studentName;
private String gender;
private Long age;
private String studentClass;
private LocalDate birthDate;
public StudentDto() {}
public StudentDto(Long studentId, String studentName,String gender,Long age,String studentClass, LocalDate birthDate) {
this.studentId = studentId;
this.studentName = studentName;
this.gender = gender;
this.age = age;
this.studentClass = studentClass;
this.birthDate = birthDate;
}
@Override
public String toString() {
return "Student [studentId=" + studentId + ", studentName=" + studentName + ", Gender=" + gender + ", Age="
+ age + ", studentClass=" + studentClass + ", birthDate=" + birthDate + "]";
}
}
SendMessageApplication.java
@SpringBootApplication
@EnableJms
public class SendMessageApplication {
public static void main(String[] args) {
SpringApplication.run(SendMessageApplication.class, args);
}
@Bean
public JmsListenerContainerFactory<?> topicListenerFactory(
ConnectionFactory connectionFactory,
DefaultJmsListenerContainerFactoryConfigurer configurer)
{
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
configurer.configure(factory, connectionFactory);
factory.setPubSubDomain(true);
return factory;
}
TopicSendMessage.java
@RestController
@RequestMapping(path = "/schoolDashboard/topic")
class TopicSendMessage {
@Autowired
private JmsTemplate jmsTemplate;
@GetMapping(path = "/publishMessage")
public void sendMessage() throws Exception{
String birthDate = "1978-10-05";
StudentDto studentDto = new StudentDto(new Long(1), "Ritesh", "Male", new Long(12), "Class-V", LocalDate.parse(birthDate));
System.out.println("TopicSendMessage.java :: Topic - Publishing Student Object....");
jmsTemplate.setPubSubDomain(true);
jmsTemplate.convertAndSend("student.topic", studentDto);
}
}
Since you're using ActiveMQ 5.x you're using JMS 1.1 and the JMS 1.1 specification states that there can only be one subscriber attached to a durable subscription. Since you're using setConcurrency("3-10")
Spring is attempting to create multiple subscribers on the same durable subscription which results in the error you're seeing. You should either:
setConcurrency("1")
. This may cause a significant degradation in performance.setSubscriptionShared(true)
since JMS 2.0 doesn't have the same limitations as JMS 1.1 regarding multiple subscribers on a durable subscription.