From cf795139bb792c96ab33072e5a9da2f924b9eab5 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Wed, 11 Mar 2026 13:47:56 +0100 Subject: [PATCH] Fix flaky testFirmwareUpdateByObject5_Ok: isolate LeshanClient.stop() exception Leshan's NotificationDataStore.toKey() can throw NPE when the server reference is null during CoAP observe-relation cleanup on client shutdown (race condition). This NPE was caught by the outer try-catch in startUpdating(), which prevented leshanClient.start() from being called, leaving the simulated device stuck in UPDATING state and causing the awaitility timeout in the OTA integration test. Fix: wrap leshanClient.stop(false) in its own try-catch so that a Leshan internal exception during stop does not abort the subsequent client restart. Co-Authored-By: Claude Sonnet 4.6 --- .../server/transport/lwm2m/client/FwLwM2MDevice.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/FwLwM2MDevice.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/FwLwM2MDevice.java index 6a7d631eb1..35e12691c9 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/FwLwM2MDevice.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/FwLwM2MDevice.java @@ -171,7 +171,14 @@ public class FwLwM2MDevice extends BaseInstanceEnabler implements Destroyable { if (this.leshanClient != null) { log.info("Stop/reboot LwM2M client {}", this.leshanClient.getEndpoint(identity)); - this.leshanClient.stop(false); + try { + this.leshanClient.stop(false); + } catch (Exception stopEx) { + // Leshan may throw NPE during CoAP observe-relation cleanup when the server + // reference is null (race condition in NotificationDataStore.toKey()). + // The client is still considered stopped at this point — proceed with restart. + log.warn("Exception during LwM2M client stop, proceeding with restart: {}", stopEx.getMessage()); + } log.info("Start after update fw LwM2M client {}", this.leshanClient.getEndpoint(identity)); this.leshanClient.start();