I'm studying JMS using the book Spring Boot Messaging by Felipe Gutierrez (2017).
It illustrates several patterns about message driven programming but, arriving at brokers, it explain Java / Spring Boot messaging with Apache ActiveMQ.
It says that the code explained will work with any other broker so I installed ActiveMQ Artemis.
I have a very simpe source code, the config:
@Configuration
public class JmsConfig {
@Bean
public MessageConverter jacksonJmsMessageConverter() {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName("_class_"); // This value can be anything, it will save the JSON class name and it must be the same for sender/receiver
return converter;
}
}
a Sender class:
@Component
public class Sender {
private final JmsTemplate jmsTemplate;
public Sender(JmsTemplate jmsTemplate){
this.jmsTemplate = jmsTemplate;
}
public void sendMessage(String destination, String message){
this.jmsTemplate.convertAndSend("test-destination", message);
}
}
and a Receiver:
....
@JmsListener(destination = "test-destinaton")
public void consumeTopicOne(String message) {
log.info("Received Message Queue/Topic1: " + message);
}
....
The application.properties
file is as follows:
spring.artemis.mode=native
spring.artemis.embedded.enabled=false
spring.artemis.broker-url=tcp://localhost:61616
spring.artemis.user=admin
spring.artemis.password=admin
spring.jms.pub-sub-domain=false
N.B.: The main class doesn't have the @EnableJms
annotation.
Now, I manage to send a message using "point to point" pattern (queue) and see it in my console just if I commented out the receiver:
If I click on message count I can see the text (with also other option). But if I try to switch to Publisher/Subscriber method, setting true this property (according to the book):
spring.jms.pub-sub-domain=true
The application runs fine and the message will be sent and received but there is no way for me to see it on the console! Even if I commented out the receiver (as I did for the queue) I still cant see the message sent.
Therefore, speaking about the queue: why I see the message only if it isn't received yet? It may be useful to have a history of sent messages..
Speaking about the Pub/Sub: Why I can't see nothing on my consolle regardless of whether the message is consumed or not?
About the book.. maybe I have to change it?
Thanks for all your replies.
I check the discussions @justin-bertram posted to me and I read:
Since you're sending your message to a JMS topic you will be subject to publish/subscribe semantics. Publish/subscribe semantics dictate that messages are only placed in valid subscriptions. When your subscriber is offline it has no valid subscription on the broker to receive the messages therefore it will miss the messages sent to it when it is offline.
You can use a durable subscriber to receive messages when the subscriber is offline
Isn't this a valid subscription:
@JmsListener(destination = "test-destinaton")
public void consumeTopicOne(String message) {
log.info("Received Message Queue/Topic1: " + message);
}
The example is taken directly from the book and I found others quite clear and very similar to mine, here for example.
I will try with a client server architecture but It seems quite strange that I can't put (for example purpose) Publisher and Subscribers in same project.
The property spring.jms.pub-sub-domain
configure how JmsTemplate and JmsMessageListenerContainer work, see the doc.
When spring.jms.pub-sub-domain= false
the destination is a JMS Queue so any sent messages can be received at any time.
When spring.jms.pub-sub-domain= true
the destination is a JMS Topic so any sent messages can be received only from the current subscribers. This explains why you don't see the messages on the console if there are no subscribers.
When a messages is received by client it is removed from the server queue. You could use a non exclusive divert to send a copy of a message to another address when it is received.