eclipse-paho / eclipse-paho/paho.mqtt.java
Lingering thread in MqttClient
- Dominant language
- Java
- Stars
- 2.3k
- Forks
- 919
- PR merge metrics
- No merged PRs in 30d
Description
Please fill out the form below before submitting, thank you!
- [x ] Bug exists Release Version 1.2.0 ( Master Branch)
- [x ] Bug exists in MQTTv3 Client on Snapshot Version 1.2.1-SNAPSHOT (Develop Branch)
- [ ] Bug exists in MQTTv5 Client on Snapshot Version 1.2.1-SNAPSHOT (Develop Branch)
I am developing a tomcat servlet that exchanges information via Mqtt. Tomcat 8, java 1.8.
I create a client in the HttpServlet init() method:
```java
if (myClient == null) {
try {
myClient = new MqttClient("tcp://localhost:1883", MqttClient.generateClientId(), persistence);
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
connOpts.setUserName("myusername");
connOpts.setPassword("mypassword".toCharArray());
connOpts.setConnectionTimeout(300);
connOpts.setKeepAliveInterval(30);
connOpts.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);
myClient.connect(connOpts);
getServletContext().setAttribute("myClient", myClient);
} catch (MqttException e) {
this.log.error ("MqttException:\n" + e.getMessage());
}
}
```
I subscribe to a message:
```java
receivedSignal = new CountDownLatch(1);
myClient.subscribe(patient_id, (topic, msg) -> {
String payload = new String(msg.getPayload());
this.log.info("Got message: " + payload);
myObjectBuilder.add("result", "good");
myObjectBuilder.add("payload", payload);
receivedSignal.countDown();
});
```
In the HttpServlet destroy() method:
```java
System.out.println("destroy");
if (receivedSignal!= null) {
System.out.println("destroy CountDownLatch: " + receivedSignal.toString());
receivedSignal.countDown();
}
if (persistence!=null) {
try {
persistence.close();
System.out.println("persistence closed in destroy");
} catch (MqttPersistenceException e) {
System.out.println ("MqttPersistenceException:\n" + e.getMessage());
}
}
if (myClient != null) {
try {
myClient.disconnect();
myClient.disconnectForcibly();
myClient.close(true);
myClient = null;
System.out.println("myClient closed in destroy");
} catch (MqttException e) {
System.out.println ("MqttException:\n" + e.getMessage());
}
}
super.destroy();
```
This works. The problem is that whenever I update the war, I get this in my log:
```
destroy
persistence closed in destroy
myClient closed in destroy
14-Jun-2019 10:58:19.836 WARNING [ContainerBackgroundProcessor[StandardEngine[Catalina]]] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [main] appears to have started a thread named [nioEventLoopGroup-2-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
sun.nio.ch.KQueueArrayWrapper.kevent0(Native Method)
sun.nio.ch.KQueueArrayWrapper.poll(KQueueArrayWrapper.java:198)
sun.nio.ch.KQueueSelectorImpl.doSelect(KQueueSelectorImpl.java:117)
sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
io.netty.channel.nio.SelectedSelectionKeySetSelector.select(SelectedSelectionKeySetSelector.java:62)
io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:791)
io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:439)
io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:906)
io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
java.lang.Thread.run(Thread.java:748)
```
I've increased the Context unloadDelay to 10 seconds, but the thread is still there. If I restart tomcat, the thread dies (as best I can tell). If I don't, eventually tomcat hangs due to the open threads. This shouldn't be an issue in production, but during development, it is highly annoying. It happens in both org.eclipse.paho.client.mqttv3-1.2.1 and in org.eclipse.paho.client.mqttv3-1.2.2-20190410.135359-1. I've seen some discussion of this in previous issues, but it seems like the threads should shut down when .close() is called.
Contributor guide
Assessment
This issue has not been assessed yet.