Repository: openhab/openhab-addons

Issue #3388: [homematic] Jetty HttpClients are not stopped properly
Created: 2018-03-22T11:59:07Z
Expected Behavior

After initialization of a DefaultHomematicGateway, the httpClient that is created to load gateway infos is stopped again.
After disposing of a DefaultHomematicGateway, e.g. because the bridge thing has been deleted, the httpClient of its XmlRpcClient is stopped.
When deleting the bridge thing during its initialization, all its created httpClients are stopped finally.

Current Behavior
All started threads for jetty httpClients from the Homematic Binding remain present after a bridge thing is deleted. If it is deleted during initialization, a httpClient is started even after disposing the DefaultHomematicGateway (i.e. the initialization is continued even after dispose() finished).
Possible Solution
In the XmlRpcClient, httpClient.destroy() is called. The proper way to dispose of a jetty HttpClient is to call httpClient.stop(). I will provide a PR for this fix. However, it only adresses the first two problems. When dispose() is called on a HomematicBridgeHandler before initialize() of that handler finishes, the jetty httpClient is still initialized and not disposed.
One solution for all these problems would be to use the newly introduced HttpClientFactory and the shared http client provided by it. The only drawback I can currently see is that the custom timeout  httpClient.setConnectTimeout(config.getTimeout() * 1000L); could not be used anymore. If you think this solution is acceptable, I will start working on a PR for that, as well.
Context
When frequently adding and removing homematic bridges or when there is a bridge thing that cannot communicate with the homematic gateway (and thus repeats initialization again and again), more and more threads accumulate. Finally, there will be an OutOfMemoryError. This might also be the cause for problems mentioned in #2849.

Duplicate issue #2849: [Homematic] java.lang.OutOfMemoryError: unable to create new native thread
Created: 2017-11-16T13:31:10Z
Hi guys,
My setup

OpenHAB 2.2 latest snapshot
OpenJDK Runtime Environment (Zulu 8.25.0.1-linux64) (build 1.8.0_152-b16)
Ubuntu 17.10 (x64) minimal - 768 MB RAM (only OpenHAB (incl. deps) installed)

no special JRE heap settings (default values)



Expected Behavior

OpenHab rule updates values from CCU2 on a regular basis (via cron job).
When current power is >70mA it will set a switch to ON
When current power is below 70mA it will start a timer to check again in 7 minutes.
if it's still below below 70mA it will set switch to OFF and will send out a message

Expected: Everything should run stable. :)
See rule:
import org.openhab.model.script.actions.Timer
var Timer timer = null

rule "Washing Machine Turned ON/OFF"
when
    Item Leistungsmesser_WM_Current changed
then
    logInfo("Leistungsmesser_WM", "Power changed!")
    val actualPower = (Leistungsmesser_WM_Current.state as DecimalType);
    logInfo("Leistungsmesser_WM", "Actual Power is " + actualPower)
	if (actualPower > 70.00){
        logInfo("Leistungsmesser_WM", "Washingmachine = ON!")
        sendCommand(Wachingmaschine_Running,ON)
        if(timer!==null) {
            logInfo("Leistungsmesser_WM", "Turns out WM is not ready yet! Cancelled timer!.")
    	    timer.cancel
    		timer = null
    	}
    } else {
        logInfo("Leistungsmesser_WM", "Power Value dropped below threshold!")
        // don't switch it off yet... wait for about 7 minutes to check if it's really ready
        if (timer === null) {
            logInfo("Leistungsmesser_WM", "Will start 7-minute-timer to check if it's really done.")
            timer = createTimer(now.plusMinutes(7)) [|
                logInfo("Leistungsmesser_WM", "Value did not change for 7 minutes - switching it off!")
                logInfo("Leistungsmesser_WM", "Washingmachine = OFF!")
                sendCommand(Wachingmaschine_Running,OFF)
                timer = null
    	    ]
        }
    }
end

Questions upfront
Is there some manual heap tweaking necessary when using 768MB RAM?
Is there a memory leak in my rule?
Is it ok, to poll the values from CCU2 every x minutes or is there a better way?
Current Behavior
I'm getting an OOM error every once in a while - of course it's not easily reproducible:

2017-11-16 13:42:00.347 [INFO ] [home.model.script.Leistungsmesser_WM] - Actual Power is 111.00
2017-11-16 13:42:00.348 [INFO ] [home.model.script.Leistungsmesser_WM] - Washingmachine = ON!
2017-11-16 13:45:00.291 [INFO ] [home.model.script.Leistungsmesser_WM] - Power changed!
2017-11-16 13:45:00.295 [INFO ] [home.model.script.Leistungsmesser_WM] - Actual Power is 110.00
2017-11-16 13:45:00.298 [INFO ] [home.model.script.Leistungsmesser_WM] - Washingmachine = ON!
2017-11-16 13:47:42.548 [WARN ] [e.jetty.util.thread.QueuedThreadPool] - qtp57733118{FAILED,8<=5<=200,i=4,q=0} rejected org.eclipse.jetty.io.ManagedSelector@2879f9f4 id=0 keys=0 selected=0
2017-11-16 13:48:00.003 [ERROR] [ore.internal.events.OSGiEventManager] - Dispatching/filtering event for subscriber 'org.eclipse.smarthome.core.events.EventSubscriber' failed: java.lang.OutOfMemoryError: unable to create new native thread
java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: unable to create new native thread
at java.util.concurrent.FutureTask.report(FutureTask.java:122) [?:?]
at java.util.concurrent.FutureTask.get(FutureTask.java:206) [?:?]
at org.eclipse.smarthome.core.common.SafeMethodCaller.callAsynchronous(SafeMethodCaller.java:194) [97:org.eclipse.smarthome.core:0.9.0.201711151730]
at org.eclipse.smarthome.core.common.SafeMethodCaller.call(SafeMethodCaller.java:83) [97:org.eclipse.smarthome.core:0.9.0.201711151730]
at org.eclipse.smarthome.core.common.SafeMethodCaller.call(SafeMethodCaller.java:67) [97:org.eclipse.smarthome.core:0.9.0.201711151730]
at org.eclipse.smarthome.core.internal.events.OSGiEventManager.dispatchESHEvent(OSGiEventManager.java:203) [97:org.eclipse.smarthome.core:0.9.0.201711151730]
at org.eclipse.smarthome.core.internal.events.OSGiEventManager.handleEvent(OSGiEventManager.java:176) [97:org.eclipse.smarthome.core:0.9.0.201711151730]
at org.eclipse.smarthome.core.internal.events.OSGiEventManager.handleEvent(OSGiEventManager.java:158) [97:org.eclipse.smarthome.core:0.9.0.201711151730]
at org.apache.felix.eventadmin.impl.handler.EventHandlerProxy.sendEvent(EventHandlerProxy.java:415) [3:org.apache.karaf.services.eventadmin:4.1.2]
at org.apache.felix.eventadmin.impl.tasks.HandlerTask.run(HandlerTask.java:90) [3:org.apache.karaf.services.eventadmin:4.1.2]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:?]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:?]
at java.lang.Thread.run(Thread.java:748) [?:?]
Caused by: java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method) ~[?:?]
at java.lang.Thread.start(Thread.java:717) ~[?:?]
at java.util.Timer.(Timer.java:160) ~[?:?]
at java.util.Timer.(Timer.java:132) ~[?:?]
at org.openhab.binding.homematic.internal.misc.DelayedExecuter.start(DelayedExecuter.java:45) ~[?:?]
at org.openhab.binding.homematic.internal.communicator.AbstractHomematicGateway.disableDatapoint(AbstractHomematicGateway.java:730) ~[?:?]
at org.openhab.binding.homematic.internal.communicator.virtual.ReloadAllFromGatewayVirtualDatapointHandler.handleCommand(ReloadAllFromGatewayVirtualDatapointHandler.java:55) ~[?:?]
at org.openhab.binding.homematic.internal.communicator.AbstractHomematicGateway$1.execute(AbstractHomematicGateway.java:552) ~[?:?]
at org.openhab.binding.homematic.internal.misc.DelayedExecuter.start(DelayedExecuter.java:61) ~[?:?]
at org.openhab.binding.homematic.internal.communicator.AbstractHomematicGateway.sendDatapoint(AbstractHomematicGateway.java:544) ~[?:?]
at org.openhab.binding.homematic.internal.communicator.AbstractHomematicGateway.sendDatapoint(AbstractHomematicGateway.java:523) ~[?:?]
at org.openhab.binding.homematic.handler.HomematicThingHandler.handleCommand(HomematicThingHandler.java:175) ~[?:?]
at org.eclipse.smarthome.core.thing.internal.profiles.ProfileCallbackImpl$1.call(ProfileCallbackImpl.java:61) ~[?:?]
at org.eclipse.smarthome.core.thing.internal.profiles.ProfileCallbackImpl$1.call(ProfileCallbackImpl.java:1) ~[?:?]
at org.eclipse.smarthome.core.common.SafeMethodCaller.executeDirectly(SafeMethodCaller.java:218) ~[?:?]
at org.eclipse.smarthome.core.common.SafeMethodCaller.callAsynchronous(SafeMethodCaller.java:189) ~[?:?]
at org.eclipse.smarthome.core.common.SafeMethodCaller.call(SafeMethodCaller.java:83) ~[?:?]
at org.eclipse.smarthome.core.common.SafeMethodCaller.call(SafeMethodCaller.java:67) ~[?:?]
at org.eclipse.smarthome.core.thing.internal.profiles.ProfileCallbackImpl.handleCommand(ProfileCallbackImpl.java:58) ~[?:?]

Does anyone have any idea? Any help would be appreciated! 👍
Regards,
Sascha

Closing comment (2018-06-11T09:03:23Z): @mastix As @FStolte mentioned, this bug may be related to #3388. Could you please verify if the issue is still valid with OpenHab 2.3.0?