-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
In what version(s) of Spring Integration are you seeing this issue?
spring-integration-mqtt-6.2.4
Describe the bug
Mqttv5ClientManager hangs in stop() if never was connected.
Mqttv3ClientManager may be affected as well.
see https://www.linkedin.com/pulse/mqtt-paho-tomcat-stop-using-shutdownsh-fails-sudhir-ravindramohan/
To Reproduce
- Instantiate Mqttv5ClientManager with automaticReconnect, while there is no MQTT Broker to connect to
- Shutdown Spring Application
- Pause in Debuggger to see hang as follows
Thread [SpringApplicationShutdownHook] (Suspended)
waiting for: Object (id=171)
Object.wait(long) line: not available [native method]
ClientState.quiesce(long) line: 1497
ClientComms.disconnectForcibly(long, long, boolean, int, MqttProperties) line: 600
ClientComms.disconnectForcibly(long, long, int, MqttProperties) line: 576
MqttAsyncClient.disconnectForcibly(long, long, int, MqttProperties) line: 888
MqttAsyncClient.disconnectForcibly(long) line: 873
MqttListener$1.stop() line: 49
MqttListener$1(SmartLifecycle).stop(Runnable) line: 117
DefaultLifecycleProcessor.doStop(Map<String,Lifecycle>, String, CountDownLatch, Set<String>) line: 344
DefaultLifecycleProcessor$LifecycleGroup.stop() line: 483
0x0000021f959848c8.accept(Object) line: not available
TreeMap$Values(Iterable<T>).forEach(Consumer<? super T>) line: 75
DefaultLifecycleProcessor.stopBeans() line: 313
DefaultLifecycleProcessor.onClose() line: 214
AnnotationConfigServletWebServerApplicationContext(AbstractApplicationContext).doClose() line: 1136
AnnotationConfigServletWebServerApplicationContext(ServletWebServerApplicationContext).doClose() line: 174
AnnotationConfigServletWebServerApplicationContext(AbstractApplicationContext).close() line: 1090
SpringApplicationShutdownHook.closeAndWait(ConfigurableApplicationContext) line: 145
0x0000021f95984230.accept(Object) line: not available
LinkedHashSet<E>(Iterable<T>).forEach(Consumer<? super T>) line: 75
SpringApplicationShutdownHook.run() line: 114
Thread.run() line: 840
Expected behavior
Troubling code
https://github.com/spring-projects/spring-integration/blob/main/spring-integration-mqtt/src/main/java/org/springframework/integration/mqtt/core/Mqttv5ClientManager.java#L153
and possibly
https://github.com/spring-projects/spring-integration/blob/main/spring-integration-mqtt/src/main/java/org/springframework/integration/mqtt/core/Mqttv3ClientManager.java#L151
Sample
Replacing the line
client.disconnectForcibly(getDisconnectCompletionTimeout());
by
if (client.isConnected()) {
client.disconnect(0).waitForCompletion(getDisconnectCompletionTimeout());
}
makes it work in this case. Not sure if that would be the universal solution. Not tested with Mqttv3ClientManager
.