in Java

Virtual Topics in ActiveMQ

A couple of days ago I published a post about the difference between queues, topics and virtual topics. Today I want to share some practical information on how to use virtual topics in ActiveMQ with Spring Boot.

Virtual Topics

Virtual topics are a combination of topics and queues. Producers will write messages to a topic while listeners will consume from their own queue. ActiveMQ will copy and duplicate each message from the topic to the actual consumer queues.

This combination of topics and queues has some advantages over conventional topics:

  • Even if a consumer is offline, no messages will be lost. ActiveMQ will copy all messages to the registered queues. As soon as a consumer comes back online, he can handle the messages stored on his queue.
  • If a consumer cannot handle a message, it will put on a dead letter queue. The consumer can be fixed and the message can be put back on his own dedicated queue without affecting the other consumer (as a topic would do).
  • We can register multiple instances of a consumer on a queue to implement a load balancing mechanism.

Using virtual topics with Spring Boot

Using virtual topics with Spring Boot is very straight forward. The configuration is based on conventions to which we will stick in the first part. However, you can easily change the conventions as we will see below.


From the point of view of the producer, virtual topics look exactly like normal topics. The only difference is the name of the topic which must have the syntax VirtualTopic.<name> by convention.


On the side of the consumer, we find a similar naming convention. The destination must match the syntax Consumer.<name>.VirtualTopic.<name> by convention.


By following these two simple naming conventions, ActiveMQ will automatically do all the magic in the background. Every message send to the virtual topic will be copied to each of the individual consumer queues.

Producer writes to: VirtualTopic.<name>
Consumer reads from: Consumer.<name>.VirtualTopic.<name>

Note that you need to explicitly state in you Java code that the destination of the producer is a topic (not a queue) by using new ActiveMQTopic(...) when sending the message.

Advanced configuration

The naming conventions above can be changed in ActiveMQ. To do this, we need to modify the activemq.xml. This means we cannot do this in our Java code – we must do it outside in our broker configuration! The configuration goes like this:

This small piece of configuration allows you to change the naming convention of your virtual queues. It also allows you to turn on the selector awareness which is de-activated by default.


Best regards,

Write a Comment


  1. Hi,

    I did the annotation conguration as per the details mentioned.
    But when my producer send the message to Virtual Topic, the vitual topic enqueue this message but does not dispatch it the consumer.
    I have just one consumer and the consumer Queue has a subscriber as 1.
    Please help.Do I need to do any other configuration.??V

    • This looks like a configuration problem in ActiveMQ. If you are able to to send messages to the topic and to register a listener to the queue, the Spring part should be fine.

      – Did you follow the naming convention? VirtualTopic.?
      – Did you change anything in your activemq.xml?

  2. I’m concerned about lost messages when a virtual topic is marked as selector aware. What happens to messages when a consumer with selectors disconnects? Are those messages that arrive to the virtual topic lost (due to there being no consumers during that time frame)?

    • No, that’s not an issue. After a listener has registered once, its queue will receive all messages even if the listener is disconnected. So the messages will not be lost.


  • Effective error handling for ActiveMQ topics – Thomas Uhrig September 20, 2017

    No, that’s not an issue. After a listener has registered once, its queue will receive all messages even if the listener is disconnected. So the messages will not be lost.