1 Reply Latest reply on Sep 12, 2017 10:18 AM by thomash

    activeMQ-MQTT integration broken in Wildfly-10.1.0.Final?

    thomash

      My question is: which combination of  netty-codec-mqtt and artemis-mqtt-protocol do I need so that they integrate with eachother and with wildfly-10.1.0.Final?

      let me elaborate:

       

      I'm trying to use the MQTT protocol on WF 10.1.0.

      I succeeded in adding the protocol to activeMQ by:

      • add protocol-folder modules\system\layers\base\org\apache\activemq\artemis\protocol\mqtt\main with the following files:
        • artemis-mqtt-protocol-1.1.0.wildfly-022.jar
        • netty-codec-mqtt-4.1.15.Final.jar
      • module.xml
      <module xmlns="urn:jboss:module:1.3" name="org.apache.activemq.artemis.protocol.mqtt">
          <resources>
          <resource-root path="artemis-mqtt-protocol-1.1.0.wildfly-022.jar" />
      <resource-root path="netty-codec-mqtt-4.1.15.Final.jar" />
          </resources>
          <dependencies>
      <module name="javax.jms.api"/>
      <module name="javax.api"/>
      <module name="io.netty"/>
      <module name="org.slf4j"/>
      <module name="org.apache.activemq.artemis"/>
      <module name="org.jboss.logging"/>
          </dependencies>
      </module>
      

       

      Also, I added

      "<module name="org.apache.activemq.artemis.protocol.mqtt" services="import" optional="true"/>"
      

      to \modules\system\layers\base\org\apache\activemq\artemis\main\module.xml. (I disabled the other protocol-modules there since I don't need them: amqp, stomp, hornetq.

       

      I added an acceptor in the active-mq subsystem in standalone.xml:

      <acceptor name="mqtt-acceptor" factory-class="org.apache.activemq.artemis.core.remoting.impl.netty.NettyAcceptorFactory">
      <param name="protocols" value="MQTT"/>
      <param name="port" value="1883"/>
      </acceptor>
      

       

       

      When the server starts, it logs, as expected:

      Aug:31,16:48:27,128 INFO  (:ServerService Thread Pool -- 4:) [org.apache.activemq.artemis.core.server] AMQ221043: Protocol module found: [artemis-mqtt-protocol]. Adding protocol support for: MQTT
      Aug:31,16:48:27,686 INFO  (:MSC service thread 1-19:) [org.wildfly.extension.messaging-activemq] WFLYMSGAMQ0016: Registered HTTP upgrade for activemq-remoting protocol handled by http-acceptor-throughput acceptor
      Aug:31,16:48:27,686 INFO  (:MSC service thread 1-12:) [org.wildfly.extension.messaging-activemq] WFLYMSGAMQ0016: Registered HTTP upgrade for activemq-remoting protocol handled by http-acceptor acceptor
      Aug:31,16:48:27,686 INFO  (:MSC service thread 1-7:) [org.wildfly.extension.messaging-activemq] WFLYMSGAMQ0016: Registered HTTP upgrade for activemq-remoting protocol handled by http-acceptor-throughput acceptor
      Aug:31,16:48:27,686 INFO  (:MSC service thread 1-2:) [org.wildfly.extension.messaging-activemq] WFLYMSGAMQ0016: Registered HTTP upgrade for activemq-remoting protocol handled by http-acceptor acceptor
      Aug:31,16:48:27,870 INFO  (:ServerService Thread Pool -- 4:) [org.apache.activemq.artemis.core.server] AMQ221020: Started Acceptor at localhost:1883 for protocols [MQTT]
      

       

      But when I send a message to it:

      Aug:31,16:48:28,357 WARNING (:Thread-3 (activemq-netty-threads-814397190):) [io.netty.channel.DefaultChannelPipeline] An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.: io.netty.handler.codec.DecoderException: java.lang.IllegalAccessError: tried to access method io.netty.handler.codec.mqtt.MqttEncoder.<init>()V from class org.apache.activemq.artemis.core.protocol.mqtt.MQTTProtocolManager
      at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:391) [netty-all-4.0.33.Final.jar:4.0.33.Final]
      at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:244) [netty-all-4.0.33.Final.jar:4.0.33.Final]
      at org.apache.activemq.artemis.core.protocol.ProtocolHandler$ProtocolDecoder.channelRead(ProtocolHandler.java:118) [artemis-server-1.1.0.wildfly-017.jar:]
      at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:318) [netty-all-4.0.33.Final.jar:4.0.33.Final]
      at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:304) [netty-all-4.0.33.Final.jar:4.0.33.Final]
      at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:846) [netty-all-4.0.33.Final.jar:4.0.33.Final]
      at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131) [netty-all-4.0.33.Final.jar:4.0.33.Final]
      at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511) [netty-all-4.0.33.Final.jar:4.0.33.Final]
      at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468) [netty-all-4.0.33.Final.jar:4.0.33.Final]
      at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382) [netty-all-4.0.33.Final.jar:4.0.33.Final]
      at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354) [netty-all-4.0.33.Final.jar:4.0.33.Final]
      at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:112) [netty-all-4.0.33.Final.jar:4.0.33.Final]
      at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_112]
      Caused by: java.lang.IllegalAccessError: tried to access method io.netty.handler.codec.mqtt.MqttEncoder.<init>()V from class org.apache.activemq.artemis.core.protocol.mqtt.MQTTProtocolManager
      at org.apache.activemq.artemis.core.protocol.mqtt.MQTTProtocolManager.addChannelHandlers(MQTTProtocolManager.java:100) [artemis-mqtt-protocol-1.1.0.wildfly-022.jar:]
      at org.apache.activemq.artemis.core.protocol.ProtocolHandler$ProtocolDecoder.decode(ProtocolHandler.java:171) [artemis-server-1.1.0.wildfly-017.jar:]
      at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:360) [netty-all-4.0.33.Final.jar:4.0.33.Final]
      ... 12 more
      

      Checking the code of MQTTProtocolManager, it indeed shows that is it creating a new MqttEncoder() https://github.com/apache/activemq-artemis/blob/1.1.0/artemis-protocols/artemis-mqtt-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/mqtt/MQTTProtocolManager.java

      However, the MqttEncoder (in netty-codec-mqtt-4.1.x), doesn't have a constructor, only a public static INSTANCE.

       

       

      When I use a later version of artemis-mqtt-protocol which uses the static MqttEncoder-instance (https://github.com/apache/activemq-artemis/blob/1.5.0/artemis-protocols/artemis-mqtt-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/mqtt/MQTTProtocolManager.java), it doesn't integrate either:

      Sep:01,10:12:15,574 ERROR (:ServerService Thread Pool -- 3:) [org.jboss.msc.service.fail] MSC000001: Failed to start service jboss.messaging-activemq.default.jms.manager: org.jboss.msc.service.StartException in service jboss.messaging-activemq.default.jms.manager: WFLYMSGAMQ0033: Failed to start service
      at org.wildfly.extension.messaging.activemq.jms.JMSService.doStart(JMSService.java:203)
      at org.wildfly.extension.messaging.activemq.jms.JMSService.access$000(JMSService.java:63)
      at org.wildfly.extension.messaging.activemq.jms.JMSService$1.run(JMSService.java:97)
      at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [rt.jar:1.8.0_112]
      at java.util.concurrent.FutureTask.run(FutureTask.java:266) [rt.jar:1.8.0_112]
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_112]
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_112]
      at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_112]
      at org.jboss.threads.JBossThread.run(JBossThread.java:320) [jboss-threads-2.2.1.Final.jar:2.2.1.Final]
      Caused by: java.lang.NoSuchMethodError: org.apache.activemq.artemis.core.protocol.mqtt.MQTTProtocolManagerFactory.internalFilterInterceptors(Ljava/lang/Class;Ljava/util/List;)Ljava/util/List;
      at org.apache.activemq.artemis.core.protocol.mqtt.MQTTProtocolManagerFactory.filterInterceptors(MQTTProtocolManagerFactory.java:49)
      at org.apache.activemq.artemis.core.remoting.server.impl.RemotingServiceImpl.resolveProtocols(RemotingServiceImpl.java:179)
      at org.apache.activemq.artemis.core.remoting.server.impl.RemotingServiceImpl.<init>(RemotingServiceImpl.java:154)
      at org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl.initialisePart1(ActiveMQServerImpl.java:1563)
      at org.apache.activemq.artemis.core.server.impl.LiveOnlyActivation.run(LiveOnlyActivation.java:61)
      at org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl.start(ActiveMQServerImpl.java:396)
      at org.apache.activemq.artemis.jms.server.impl.JMSServerManagerImpl.start(JMSServerManagerImpl.java:381)
      at org.wildfly.extension.messaging.activemq.jms.JMSService.doStart(JMSService.java:199)
      ... 8 more
      

       

      Is MQTT-support supposed to work with wildfly? I guess it should.

      I didn't find any issues in jira about this, should I file one?

      (for completeness, I also tried with artemis-mqtt-protocol-1.1.0.wildfly-017.jar, wich is the compile-dependency)

        • 1. Re: activeMQ-MQTT integration broken in Wildfly-10.1.0.Final?
          thomash

          Update: after some searching I found that artemis-mqtt-protocol-1.1.0 has a compile-dependency to netty-4.0.30.Final (activemq-artemis/pom.xml at 1.1.0 · apache/activemq-artemis · GitHub )

          And netty-codec-mqtt-5.0.0.Alpha2.

          When using those versions, it seems better.

          So my configuration is now

              <resources>
              <resource-root path="artemis-mqtt-protocol-1.1.0.wildfly-017.jar" />
          <resource-root path="netty-codec-mqtt-5.0.0.Alpha2.jar" />
              </resources>
          

           

          I also had to add the 'host' param to the acceptor:

           <acceptor name="mqtt-acceptor" factory-class="org.apache.activemq.artemis.core.remoting.impl.netty.NettyAcceptorFactory">  
             <param name="protocols" value="MQTT"/>  
             <param name="port" value="1883"/>  
             <param name="host" value="${hostname}"/>
            </acceptor>