activemq-artemis

ActiveMQ Artemis embedded "queue does not exist"


I'm trying to set up an embedded ActiveMQ broker, but when I try to connect to a topic (a multicast queue), it says the queue does not exist.

Can someone please point out what I'm doing wrong? I feel like I'm missing a URI in the address configuration, but I can't figure out how to set it.

Thanks.

public class Example {

    public Example() throws Exception {
        EmbeddedActiveMQ broker = new EmbeddedActiveMQ();
        broker.setConfigResourcePath("file:cfg/broker.xml");
        broker.start();

        CoreAddressConfiguration cac = new CoreAddressConfiguration();
        cac.setName("example");
        cac.addRoutingType(RoutingType.MULTICAST);
        broker.getConfiguration().addAddressConfiguration(cac);
    }

    public static void main(String[] args) throws Exception {
        Example example = new Example();

        ServerLocator locator = ActiveMQClient.createServerLocator("vm://0");
        ClientSessionFactory factory = locator.createSessionFactory();
        ClientSession session = factory.createSession();
        session.start();

        ClientConsumer consumer = session.createConsumer("example");
        consumer.setMessageHandler(new MessageHandler() {
            @Override
            public void onMessage(ClientMessage message) {
                System.out.println("got message: " + message);
            }
        });
    }
}

My config:

<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:activemq" xsi:schemaLocation="urn:activemq /schema/artemis-server.xsd">
    <core xmlns="urn:activemq:core">
        <persistence-enabled>false</persistence-enabled>
        <security-enabled>false</security-enabled>
        <acceptors>
            <acceptor name="in-vm">vm://0</acceptor>
        </acceptors>
    </core>
</configuration>

When I run this, I get:

INFO: AMQ601265: User anonymous@invm:0 is creating a core consumer on target resource ServerSessionImpl() with parameters: [0, example, null, 0, false, true, null]
Exception in thread "main" ActiveMQNonExistentQueueException[errorType=QUEUE_DOES_NOT_EXIST message=AMQ229017: Queue example does not exist]

EDIT: I think I was missing adding a queue to the address, so I've added this:

CoreAddressConfiguration cac = new CoreAddressConfiguration();
cac.setName("address1");
cac.addRoutingType(RoutingType.MULTICAST);
QueueConfiguration qc = QueueConfiguration.of("q1").setAddress("q1").setRoutingType(RoutingType.MULTICAST);
cac.addQueueConfiguration(qc);
Configuration configuration = broker.getConfiguration();
configuration.addAddressConfiguration(cac);
broker.setConfiguration(configuration);

and the consumer consumes "q1", but I still get the same exception.


Solution

  • I think the problem here is that you're mixing two paradigms for configuring the broker - XML and API.

    First, you reference a broker.xml file and start the broker:

    EmbeddedActiveMQ broker = new EmbeddedActiveMQ();
    broker.setConfigResourcePath("file:cfg/broker.xml");
    broker.start();
    

    This creates a running, embedded broker instance based on the XML configuration.

    However, then you add to the broker configuration programmatically, i.e.:

    CoreAddressConfiguration cac = new CoreAddressConfiguration();
    cac.setName("example");
    cac.addRoutingType(RoutingType.MULTICAST);
    broker.getConfiguration().addAddressConfiguration(cac);
    

    This actually doesn't change the configuration of the running broker since the broker only reads the Configuration when it first starts. You'd have to restart the broker for it to pick up these changes or potentially use the management API to change the broker's configuration at runtime.

    That said, I recommend you settle on either the XML or the configuration API for all your configuration, e.g.:

    <configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:activemq" xsi:schemaLocation="urn:activemq /schema/artemis-server.xsd">
        <core xmlns="urn:activemq:core">
            <persistence-enabled>false</persistence-enabled>
            <security-enabled>false</security-enabled>
            <acceptors>
                <acceptor name="in-vm">vm://0</acceptor>
            </acceptors>
            <addresses>
                <address name="q1">
                    <multicast>
                        <queue name="q1">
                    </multicast>
                </address>
            </addresses>
        </core>
    </configuration>
    

    Or:

    EmbeddedActiveMQ broker = new EmbeddedActiveMQ()
       .setConfiguration(new ConfigurationImpl()
                            .setPersistenceEnabled(false)
                            .setSecurityEnabled(false)
                            .addAcceptorConfiguration("in-vm", "vm://0")
                            .addQueueConfiguration(QueueConfiguration
                                                      .of("q1")
                                                      .setAddress("q1")
                                                      .setRoutingType(RoutingType.MULTICAST)))
       .start();
    

    Also, keep in mind that while you invoke setMessageHandler you're not doing anything to keep main from returning immediately after in which case all your client resources will fall out of scope and be useless. If you actually want to receive a message you need to ensure main doesn't return while the consumer waits.