I am sending to an ActiveMQ Artemis topic. The topic is created using the following code:
@Bean
public ActiveMQTopic sampleTopic(){
return new org.apache.activemq.artemis.jms.client.ActiveMQTopic("topicName");
}
If I send the message to a topic using the convertAndSend
with sampleTopic
as argument I receive the message in the listener.
@Autowired
private Topic sampleTopic;
jmsTemplate.convertAndSend(sampleTopic, jsonMessage, m -> {
m.setStringProperty("type", "new");
m.setStringProperty("sender", "abc");
return m;
});
But if I send the message using the String
name of topic as an argument to the convertAndSend()
the message is not received by the listener.
jmsTemplate.convertAndSend("topicName", jsonMessage, m -> {
m.setStringProperty("type", "new");
m.setStringProperty("sender", "abc");
return m;
});
The @JmsListener
looks like this:
@JmsListener(destination = "topicName",
containerFactory = "topicJmsListenerContainerFactory",
subscription = "new",
selector = "type = 'new' and sender = 'abc'")
@Transactional
public void onMessage(String payload) {
}
Configuration:
@Configuration
@EnableJms
@Profile("local")
@PropertySource("classpath:application-local.properties")
public class MessagingConfigArtemis {
private static final String ARTEMIS_BROKER_URL = "tcp://localhost:61616";
private static final String ARTEMIS_USERNAME = "artemis";
private static final String ARTEMIS_PASSWORD = "artemis";
@Bean
public ConnectionFactory jmsConnectionFactory() throws JMSException {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
connectionFactory.setBrokerURL(ARTEMIS_BROKER_URL);
connectionFactory.setUser(ARTEMIS_USERNAME);
connectionFactory.setPassword(ARTEMIS_PASSWORD);
return connectionFactory;
}
@Bean
public JmsTemplate jmsTemplate() throws JMSException {
JmsTemplate jmsTemplate = new JmsTemplate(jmsConnectionFactory());
return jmsTemplate;
}
@Bean
public JmsListenerContainerFactory<DefaultMessageListenerContainer> jmsListenerContainerFactory(ConnectionFactory connectionFactory) {
DefaultJmsListenerContainerFactory returnValue = new DefaultJmsListenerContainerFactory();
returnValue.setConnectionFactory(connectionFactory);
return returnValue;
}
@Bean
public JmsListenerContainerFactory<DefaultMessageListenerContainer> topicJmsListenerContainerFactory(ConnectionFactory connectionFactory) {
DefaultJmsListenerContainerFactory returnValue = new DefaultJmsListenerContainerFactory();
returnValue.setConnectionFactory(connectionFactory);
returnValue.setSubscriptionShared(true);
returnValue.setSubscriptionDurable(true);
returnValue.setPubSubDomain(Boolean.TRUE);
return returnValue;
}
}
As per my understanding the listener should be able to recieve the message from the topic, for both type of convertAndSend()
methods (i.e. one with String
and other with Topic
as argument). Can anyone help?
By default, Spring Boot creates a JmsTemplate
configured to transmit to queues by having pubSubDomain
set to false
. The JmsMessageListenerContainer
is also configured the same way. To override and publish to topics, set spring.jms.pub-sub-domain=true
through Spring Boot’s property settings (either inside application.properties
or by setting an environment variable).