We\'re experiencing an issue with one of our MQTT subscribers in Spring integration (4.0.3.RELEASE running on Tomcat 7 with the Paho MQTT Client 0.4.0).
The issue i
First of all share, please, the versions of Spring Integration and Paho Client.
According to the after doing a couple of redeploys
I see this code from CommsReceiver#.stop()
:
if (!Thread.currentThread().equals(recThread)) {
try {
// Wait for the thread to finish.
recThread.join();
}
catch (InterruptedException ex) {
}
}
Where Thread.join()
:
* Waits for this thread to die.
I'm really not sure what it means and how it should go further on that wait
, but won't the redeploy
be a bottleneck to allow for those daemons
to continue to live, because the main Thread doesn't die?
Following up from my comments in @Artem's answer...
There appears to be a deadlock in the Paho client. See line 573 of your Gist; the Snd
thread is waiting for the Rec
thread to terminate. At line 586, the Rec
thread is blocked because the inbound queue is full (10). For all the cases that look like this, there is no Call
thread. So the queue full condition will never be cleared. Notice at line 227 the trifecta of threads are working fine (presumably a reconnection after redeploy?).
With the dead threads, there is no Call
thread.
I think the problem is in the Paho client - in the CommsCallback.run()
method, there is a catch on Throwable
, which closes the connection, but because the queue is full, the Rec
thread is never notified (and so won't clean up). So it seems the message delivery is throwing an exception and, if the queue is full, causes this deadlock.
The Paho client needs a fix but in the meantime, we can figure out what the exception is.
If the exception is downstream of the inbound gateway, you should see a log...
logger.error("Unhandled exception for " + message.toString(), e);
Since this log is produced in MqttCallback.messageArrived()
, if you are not seeing such errors, the problem may be in the Paho client itself.
The exception handling in CommsCallback
looks like this...
} catch (Throwable ex) {
// Users code could throw an Error or Exception e.g. in the case
// of class NoClassDefFoundError
// @TRACE 714=callback threw exception
log.fine(className, methodName, "714", null, ex);
running = false;
clientComms.shutdownConnection(null, new MqttException(ex));
}
(that is where they should call spaceAvailable.notifyAll()
to wake the (dying) Rec
thread).
So, turning on FINE logging for the Paho client should tell you where/what the exception is.