Migrate existing Java Message Service (JMS) 2.0 applications from Apache ActiveMQ to Azure Service Bus
This article discusses how to modify an existing Java Message Service (JMS) 2.0 application that interacts with a JMS Broker to interact with Azure Service Bus instead. In particular, the article covers migrating from Apache ActiveMQ or Amazon MQ.
Azure Service Bus supports Java 2 Platform, Enterprise Edition and Spring workloads that use the JMS 2.0 API over Advanced Message Queueing Protocol (AMQP).
Before you start
Differences between Azure Service Bus and Apache ActiveMQ
Azure Service Bus and Apache ActiveMQ are both message brokers, functioning as JMS providers for client applications to send messages to and receive messages from. They both enable the point-to-point semantics with queues, and publish-subscribe semantics with topics and subscriptions.
Even so, there are some differences between the two, as the following table shows:
|Category||ActiveMQ||Azure Service Bus|
|Application tiering||Clustered monolith||Two-tier
(gateway + back end)
||Managed platform as a service (PaaS)|
|Message size||Customer configurable||1 MB (Premium tier)|
|High availability||Customer managed||Platform managed|
|Disaster recovery||Customer managed||Platform managed|
Current supported and unsupported features
The following table lists the Java Message Service (JMS) features that Azure Service Bus currently supports. It also shows features that are unsupported.
|Message Producer /
noLocal is currently not supported
|Shared durable subscriptions||
|Unshared durable subscriptions||
noLocal is currently not supported and should be set to false
|Shared non-durable subscriptions||
|Unshared non-durable subscriptions||
noLocal is currently not supported and should be set to false
|Message selectors||depends on the consumer created||Supported|
|Delivery Delay (scheduled messages)||
|Cross entity transactions||
|Distributed transactions||Not supported|
The two-tiered nature of Azure Service Bus affords various business continuity capabilities (high availability and disaster recovery). However, there are some considerations when you're using JMS features.
In case of service bus upgrades and restarts, temporary queues or topics are deleted. If your application is sensitive to data loss on temporary queues or topics, don't use temporary queues or topics. Use durable queues, topics, and subscriptions instead.
As part of migrating and modifying your client applications to interact with Azure Service Bus, the data held in ActiveMQ isn't migrated to Service Bus. You might need a custom application to drain the ActiveMQ queues, topics, and subscriptions, and then replay the messages to the queues, topics, and subscriptions of Service Bus.
Authentication and authorization
Azure role-based access control (Azure RBAC), backed by Azure Active Directory, is the preferred authentication mechanism for Service Bus. Because Azure RBAC, or claim-based authentication, isn't currently supported by Apache QPID JMS, however, you should use SAS keys for authentication.
You use the following components and versions while you're writing the JMS applications:
|Java Message Service (JMS) API||1.1 or greater|
Ensure that AMQP ports are open
Service Bus supports communication over the AMQP protocol. For this purpose, enable communication over ports 5671 (AMQP) and 443 (TCP). Depending on where the client applications are hosted, you might need a support ticket to allow communication over these ports.
Service Bus supports only AMQP 1.0 protocol.
Set up enterprise configurations
Service Bus enables various enterprise security and high availability features. For more information, see:
- Virtual network service endpoints
- Service side encryption with customer managed key (BYOK)
- Private endpoints
- Authentication and authorization
Monitoring, alerts and tracing
For each Service Bus namespace, you publish metrics onto Azure Monitor. You can use these metrics for alerting and dynamic scaling of resources allocated to the namespace.
For more information about the different metrics and how to set up alerts on them, see Service Bus metrics in Azure Monitor. You can also find out more about client side tracing for data operations and operational/diagnostic logging for management operations.
Metrics - New Relic
You can correlate which metrics from ActiveMQ map to which metrics in Azure Service Bus. See the following from the New Relic website:
Currently, New Relic doesn't have direct, seamless integration with ActiveMQ, but they do have metrics available for Amazon MQ. Because Amazon MQ is derived from ActiveMQ, the following table maps the New Relic metrics from Amazon MQ to Azure Service Bus.
|Metric grouping||Amazon MQ/ActiveMQ metric||Azure Service Bus metric|
||Use subscription metrics|
||Use queue/topic/subscription level
To migrate your existing JMS 2.0 application to interact with Service Bus, follow the steps in the next several sections.
Export the topology from ActiveMQ and create the entities in Service Bus (optional)
To ensure that client applications can seamlessly connect with Service Bus, migrate the topology (including queues, topics, and subscriptions) from Apache ActiveMQ to Service Bus.
For JMS applications, you create queues, topics, and subscriptions as a runtime operation. Most JMS providers (message brokers) give you the ability to create these at runtime. That's why this export step is considered optional. To ensure that your application has the permissions to create the topology at runtime, use the connection string with SAS
To do this:
- Use the ActiveMQ command line tools to export the topology.
- Re-create the same topology by using an Azure Resource Manager template.
- Run the Azure Resource Manager template.
Import the maven dependency for Service Bus JMS implementation
To ensure seamless connectivity with Service Bus, add the
azure-servicebus-jms package as a dependency to the Maven
pom.xml file, as follows:
<dependencies> ... <dependency> <groupId>com.microsoft.azure</groupId> <artifactId>azure-servicebus-jms</artifactId> </dependency> ... </dependencies>
Application server configuration changes
This part is customized to the application server that is hosting your client applications connecting to ActiveMQ.
If you're using a Spring boot application to connect to ActiveMQ, you want to remove the ActiveMQ-specific properties from the
spring.activemq.broker-url=<ACTIVEMQ BROKER URL> spring.activemq.user=<ACTIVEMQ USERNAME> spring.activemq.password=<ACTIVEMQ PASSWORD>
Then, add the Service Bus-specific properties to the
The next step is to replace the instance of
ActiveMQConnectionFactory with the
The actual code changes are specific to the application and how dependencies are managed, but the following sample provides the guidance on what should be changed.
Previously, you might have been instantiating an object of
ActiveMQConnectionFactory, as follows:
String BROKER_URL = "<URL of the hosted ActiveMQ broker>"; ConnectionFactory factory = new ActiveMQConnectionFactory(BROKER_URL); Connection connection = factory.createConnection(); connection.start();
Now, you're changing this to instantiate an object of
ServiceBusJmsConnectionFactory, as follows:
ServiceBusJmsConnectionFactorySettings settings = new ServiceBusJmsConnectionFactorySettings(); String SERVICE_BUS_CONNECTION_STRING = "<Service Bus Connection string>"; ConnectionFactory factory = new ServiceBusJmsConnectionFactory(SERVICE_BUS_CONNECTION_STRING, settings); Connection connection = factory.createConnection(); connection.start();
Now that you have modified the application to start sending and receiving messages from Service Bus, you should verify that it works as you expect. When that's done, you can proceed to further refine and modernize your application stack.
Use the Spring Boot Starter for Azure Service Bus JMS for seamless integration with Service Bus.
To learn more about Service Bus messaging and JMS, see: