Details
-
Bug
-
Resolution: Done
-
Major
-
JBoss A-MQ 6.0, JBoss A-MQ 6.1
-
None
Description
The broker's transport connector
<transportConnector name="mqtt+nio+ssl" uri="mqtt+nio+ssl://0.0.0.0:1885"/>
may hang when accepting a new MQTT client.
Getting a broker thread dump shows its NIO worker thread is spinning:
"ActiveMQ NIO Worker 2" daemon prio=5 tid=0x00007fa796020800 nid=0x9103 runnable [0x000000011a059000] java.lang.Thread.State: RUNNABLE at org.apache.activemq.transport.mqtt.MQTTCodec.processHeader(MQTTCodec.java:104) at org.apache.activemq.transport.mqtt.MQTTCodec.parse(MQTTCodec.java:55) at org.apache.activemq.transport.mqtt.MQTTNIOSSLTransport.processCommand(MQTTNIOSSLTransport.java:56) at org.apache.activemq.transport.nio.NIOSSLTransport.serviceRead(NIOSSLTransport.java:199) at org.apache.activemq.transport.nio.NIOSSLTransport$1.onSelect(NIOSSLTransport.java:154) at org.apache.activemq.transport.nio.SelectorSelection.onSelect(SelectorSelection.java:94) at org.apache.activemq.transport.nio.SelectorWorker$1.run(SelectorWorker.java:119) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:744)
The code of MQTTCodec.processHeader() reads as follows:
private int processHeader(byte header, DataByteArrayInputStream input) { this.header = header; byte digit; int multiplier = 1; int read = 0; int length = 0; do { digit = input.readByte(); length += (digit & 0x7F) * multiplier; multiplier <<= 7; read++; } while ((digit & 0x80) != 0); ... }
Debugging shows the code does not break out of the while loop. At some stage the call to
digit = input.readByte();
only returns -1 which does not meet the exit criteria for the while loop. As a result the code spins forever in that loop. Clients wait forever for a result from the broker.