jakarta-eerabbitmqjmswildflymessage-driven-bean

How to configure Wildfly to connect to RabbitMQ?


I'm having difficulty configuring JB EAP7 to use RabbitMQ as a message broker. I have created a rabbitmq module and defined it as a global module in my standalone-ha.xml.

modules/system/layers/base/com/rabbitmq/main/module.xml:

<module xmlns="urn:jboss:module:1.1" name="com.rabbitmq">
    <resources>
        <resource-root path="rabbitmq-jms-1.7.0.jar"/>
        <resource-root path="amqp-client-4.2.0.jar" />
    </resources>
    <dependencies>
       <module name="javax.api" />
       <module name="javax.transaction.api"/>
       <module name="org.slf4j"/>
    </dependencies>
</module>

JB7 starts without issues. But I see the following in my server.log, showing that the MDB is trying to bind to an ActiveMQ connection (the default provider in Wildfly I guess):

2017-08-29 17:24:09,193 INFO  [org.jboss.as.ejb3]WFLYEJB0042: Started message driven bean 'Subscriber' with 'activemq-ra' resource adapter
2017-08-29 17:24:09,368 INFO  [javax.enterprise.resource.webcontainer.jsf.config]Initializing Mojarra 2.2.12-jbossorg-2  for context '/webapp-0.0.1-SNAPSHOT'
2017-08-29 17:24:09,462 INFO  [org.apache.activemq.artemis.ra]AMQ151000: awaiting topic/queue creation java:/global/mq/kodo
2017-08-29 17:24:10,103 INFO  [org.wildfly.extension.undertow]WFLYUT0021: Registered web context: /webapp-0.0.1-SNAPSHOT
2017-08-29 17:24:10,285 INFO  [org.jboss.as.server]WFLYSRV0010: Deployed "webapp-0.0.1-SNAPSHOT.war" (runtime-name : "webapp-0.0.1-SNAPSHOT.war")
2017-08-29 17:24:10,286 INFO  [org.jboss.as.server]WFLYSRV0010: Deployed "kodo-jdo.rar" (runtime-name : "kodo-jdo.rar")
2017-08-29 17:24:11,465 INFO  [org.apache.activemq.artemis.ra]AMQ151001: Attempting to reconnect org.apache.activemq.artemis.ra.inflow.ActiveMQActivationSpec(ra=org.apache.activemq.artemis.ra.ActiveMQResourceAdapter@78712571 destination=java:/global/mq/kodo destinationType=javax.jms.Queue ack=Auto-acknowledge durable=false clientID=null user=null maxSession=15)

I'm not sure how to identify in my MDB that I want the MDB to use my RabbitMQ defined ConnectionFactory. My MDB is defined as:

@MessageDriven(
        activationConfig = {
        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
        @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "java:/global/mq/kodo") })
public class Subscriber implements MessageListener {

    public void onMessage(final Message message) {
        try {
            System.out.println(message.getBody(Object.class).toString());
        } catch (JMSException e) {
            // TODO Auto-generated catch block
            throw new RuntimeException(e);
        }
    }
}

but I cannot find documentation where/how to specify the ConnectionFactory. I've tried adding a @JMSConnectionFactory( String JNDI) annotation to my class and I'm still getting the same result.

Am I missing something in my RabbitMQ module definition? Is my MDB not annotated correctly? What do I need to do in order to configure my MDB to use my RabbitMQ ConnectionFactory to connect to the Message Broker?


Solution

  • If you want to use another broker for MDBs you have to change a configuration in Wildfly configuration file, which only exist for full profile, as MDB are part of Java EE Full profile, not the web profile. This configuration is for example available in standalone-full.xml file:

    <mdb>
        <resource-adapter-ref resource-adapter-name="${ejb.resource-adapter-name:activemq-ra.rar}"/>
        <bean-instance-pool-ref pool-name="mdb-strict-max-pool"/>
    </mdb>
    

    Unfortunately, it seems it is not possible to use MDBs yet to connect to RabbitMQ via the RabbitMQ JMS Client. This is due to the fact that some optional JMS client specification features are not implemented in it. See RabbitMQ Jms client compliance page

    So to use Message Listeners connecting to RabbitMQ (if you don't want to poll a queue), you could try to declare them manually with the help of setMessageListener method and CDI. See this answer for details. However I'm not sure whether this last one would work or not in Wildfly actually (to be tested in Wildfly started with Java EE Web Profile), as per the javadoc this method throws an exception:

    if the JMS provider fails to set the MessageConsumer's MessageListener for one of the following reasons: an internal error has occurred or this method has been called in a Java EE web or EJB application (though it is not guaranteed that an exception is thrown in this case)

    Note that to use The Wildfly configuration described in RabbitMQ JMS Client documentation, you have to use the 1.7.0 version, as this Pull request enable Wildfly configuration.

    I will try to share the piece of code I did when I tested the RabbitMQ JMS Client integration to wildfly