Reputation: 426
I have an embedded ActiveMQ Artemis 2.17.0 broker that has no pre-configured queues. I'd like for the client to connect to the broker and have its queue created automatically if it doesn't exist. This works just fine the 1st time when I run the client but on the second time I connect again to the broker the client throws an error :
errorType=QUEUE_EXISTS message=AMQ229019: Queue hornetq already exists on address router
Is it possible to configure the client or the server in such a way that if a queue is already in existence it should not attempt to recreate it again?
Below are the programs I am running:
Server
try {
ActiveMQServer server = new ActiveMQServerImpl(new ConfigurationImpl()
.setPersistenceEnabled(true)
.setBindingsDirectory("./router/data/bindings")
.setLargeMessagesDirectory("./router/data/large")
.setPagingDirectory("./router/data/paging")
.setJournalDirectory("./router/data/journal")
.setSecurityEnabled(false)
.addAcceptorConfiguration("tcp", "tcp://0.0.0.0:61617?protocols=CORE,AMQP"));
server.start();
} catch (Exception ex) {
System.err.println(ex);
}
Client
ServerLocator serverLocator = ActiveMQClient.createServerLocator("tcp://127.0.0.1.3:61617");
ClientSessionFactory factory = serverLocator.createSessionFactory();
ClientSession session = factory.createSession();
session.createQueue(new QueueConfiguration("router::hornetq")
.setAutoCreateAddress(Boolean.FALSE)
.setAutoCreated(Boolean.FALSE)
.setRoutingType(RoutingType.ANYCAST));
ClientProducer producer = session.createProducer("router::hornetq");
ClientMessage message = session.createMessage(true);
message.getBodyBuffer().writeString("Core Queue Message");
producer.send(message);
session.start();
ClientConsumer consumer = session.createConsumer("router::hornetq");
ClientMessage msgReceived = consumer.receive();
System.out.println("message = " + msgReceived.getBodyBuffer().readString());
session.close();
I'm using the fully qualified queue name here (i.e. router::hornetq
) because I have multiple queues on the router
address.
Upvotes: 1
Views: 1489
Reputation: 35008
Your client is using the core API which is a low-level API that does not support auto-queue creation. Your client is creating (or attempting to create) the queue manually, e.g.:
session.createQueue(new QueueConfiguration("router::hornetq")
.setAutoCreateAddress(Boolean.FALSE)
.setAutoCreated(Boolean.FALSE)
.setRoutingType(RoutingType.ANYCAST));
The exception you're seeing is no doubt being thrown here if the queue exists already. Creating a queue is not idempotent so you have 3 options from what I can see:
ActiveMQQueueExistsException
that is being thrown here and ignore it.ClientSession.queueQuery
to see if the queue exists before you attempt to create it. If it exists then don't try to create it again. If it doesn't exist then create it. That said, if you have lots of clients like this running concurrently it's still possible you could get an ActiveMQQueueExistsException
due to race conditions between the clients.A few other things are worth mentioning:
ClientSession.createAddress()
you probably want to use setAutoCreateAddress(Boolean.TRUE)
.router::hornetq
. It can just use hornetq
and it will receive any messages sent to the hornetq
queue. Queue names are universally unique in the broker.Upvotes: 1