Migrate from #Wildfly 10 + external #ActiveMQ to #Wildfly 13 + embedded #Artemis

By | March 27, 2019

As I mentioned in a previous post I am a long time user of WildFly 10 and now in the process of upgrading to WildFly 13. Yes, not the latest version because I have some legacy source code constraints that forces me to not consider yet WildFly 14 and up.

WildFly 13 includes an Artemis implementation of the JMS engine. This means that all the internal JMS queues used by some enterprise applications no longer need to be defined in an external ActiveMQ server.

The following is a short tutorial on how to migrate your setup from Wildfly 10 + queues defined in ActiveMQ to WildFly 13 with queues defined in the included Artemis engine.

All the configurations are done in the standalone.xml configuration file from the wildfly/standalone/configuration directory.

I am going to explain the changes to each relevant section.

WildFly 10 configuration

Under WildFly 10 we needed to include a package with a resource addaptor to be able to access the external ActiveMQ server. The package I was using was activemq.rar from Maven central https://search.maven.org/search?q=a:activemq-rar

Under system-properties we needed to include it:

	...
        <subsystem xmlns="urn:jboss:domain:ejb3:4.0">
            <session-bean>
                <stateless>
                    <bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
                </stateless>
                <stateful default-access-timeout="5000" cache-ref="simple" passivation-disabled-cache-ref="simple"/>
                <singleton default-access-timeout="5000"/>
            </session-bean>
            <mdb>
                <resource-adapter-ref resource-adapter-name="activemq.rar"/>
                <bean-instance-pool-ref pool-name="mdb-strict-max-pool"/>
            </mdb>
        ...

Then a section for the resource adaptor describing the configuration for the queues

	...
        <subsystem xmlns="urn:jboss:domain:resource-adapters:4.0">
            <resource-adapters>
                <resource-adapter id="activemq.rar">
                    <archive>
                        activemq.rar
                    </archive>
                    <transaction-support>XATransaction</transaction-support>
                    <config-property name="ServerUrl">
                        tcp://activemq:61616?jms.rmIdFromConnectionId=true
                    </config-property>
                    <config-property name="UserName">
                        admin
                    </config-property>
                    <config-property name="Password">
                        secure12
                    </config-property>
                    <connection-definitions>
                        <connection-definition class-name="org.apache.activemq.ra.ActiveMQManagedConnectionFactory" jndi-name="java:/JmsXA" enabled="true" pool-name="ConnectionFactory">
                            <xa-pool>
                                <min-pool-size>10</min-pool-size>
                                <max-pool-size>200</max-pool-size>
                                <prefill>true</prefill>
                                <is-same-rm-override>false</is-same-rm-override>
                            </xa-pool>
                            <recovery>
                                <recover-credential>
                                    <user-name>admin</user-name>
                                    <password>pass</password>
                                </recover-credential>
                            </recovery>
                        </connection-definition>
                    </connection-definitions>
                    <admin-objects>
                        ...
                        <admin-object class-name="org.apache.activemq.command.ActiveMQQueue" jndi-name="java:/queue/startup" use-java-context="true" pool-name="startup">
                            <config-property name="PhysicalName">
                                myapp.startup
                            </config-property>
                        </admin-object>
                        <admin-object class-name="org.apache.activemq.command.ActiveMQQueue" jndi-name="java:/queue/mq.sys.dmq" use-java-context="true" pool-name="mq.sys.dmq">
                            <config-property name="PhysicalName">
                                myapp.DLQ
                            </config-property>
                        </admin-object>
			...
                    </admin-objects>
                </resource-adapter>
            </resource-adapters>
        </subsystem>
	...

Note that we had to define an URL to the external ActiveMQ server and credentials to connect to it.

Just 2 queues are defined in this example: startup (an application queue) and the dead message queue mq.sys.dmq

Note that activemq-broker-…jar and activemq-client-…jar libraries must be added in a library package under wildlfy/modules to be visible by wildfly.

WildFly 13 configuration

We no longer need to deploy an external resource adapter package. We just have to tell WildFly to import in the configuration the MQ engine module that comes with the release.

In the extension section make sure to include the following:

...
<server xmlns="urn:jboss:domain:7.0">
    <extensions>
	...
        <extension module="org.wildfly.extension.messaging-activemq"/>
        ...
    </extensions>
...

Then simply define the queues as following:

	...
        <subsystem xmlns="urn:jboss:domain:messaging-activemq:3.0">
            <server name="default">
                <security enabled="false"/>
                <management address="localhost" jmx-enabled="true" jmx-domain="org.apache.activemq.artemis"/>
                <security-setting name="#">
                    <role name="guest" send="true" consume="true" create-non-durable-queue="true" delete-non-durable-queue="true"/>
                </security-setting>
                <address-setting name="#" dead-letter-address="queue/mq.sys.dmq" expiry-address="jms.queue.ExpiryQueue" max-size-bytes="10485760" page-size-bytes="2097152" message-counter-history-day-limit="10"/>
                <http-connector name="http-connector" socket-binding="http" endpoint="http-acceptor"/>
                <http-connector name="http-connector-throughput" socket-binding="http" endpoint="http-acceptor-throughput">
                    <param name="batch-delay" value="50"/>
                </http-connector>
                <in-vm-connector name="in-vm" server-id="0">
                    <param name="buffer-pooling" value="false"/>
                </in-vm-connector>
                <http-acceptor name="http-acceptor" http-listener="default"/>
                <http-acceptor name="http-acceptor-throughput" http-listener="default">
                    <param name="batch-delay" value="50"/>
                    <param name="direct-deliver" value="false"/>
                </http-acceptor>
                <remote-acceptor name="internal-messaging-acceptor" socket-binding="internal-messaging"/>
                <in-vm-acceptor name="in-vm" server-id="0">
                    <param name="buffer-pooling" value="false"/>
                </in-vm-acceptor>
                <jms-queue name="ExpiryQueue" entries="java:/jms/queue/ExpiryQueue"/>
                <jms-queue name="mq.sys.dmq" entries="java:/queue/mq.sys.dmq java:jboss/exported/queue/mq.sys.dmq"/>
                <jms-queue name="startup" entries="queue/startup java:jboss/exported/jms/queue/startup"/>
                <jms-queue name="dummy" entries="queue/dummy java:jboss/exported/jms/queue/dummy"/>
                <connection-factory name="InVmConnectionFactory" entries="java:/ConnectionFactory" connectors="in-vm"/>
                <connection-factory name="RemoteConnectionFactory" entries="java:jboss/exported/jms/RemoteConnectionFactory" connectors="http-connector"/>
                <pooled-connection-factory name="activemq-ra" entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory" connectors="in-vm" transaction="xa"/>
            </server>
        </subsystem>
	...

Note that we do not have to specify any connection URL to the MQ server and no credentials to connect to it.

Just 2 queues are defined in this example: startup (an application queue) and the dead message queue mq.sys.dmq

There are two additional queues “ExpiryQueue” and “dummy” that are required by the application server.

This is all.

Advertisements

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.