From 010cebe5c0d05611cb1f7bd1a56f6ac928297b0b Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Mon, 23 Feb 2026 14:26:54 +0200 Subject: [PATCH] Update TBEL to 1.2.9 to fix script execution failures on repeated runs TBEL 1.2.9 fixes two issues that caused TBEL scripts to fail or produce incorrect results when executed multiple times: 1. Thread-safety: OptimizerFactory.defaultOptimizer was not volatile, so worker threads could use DynamicOptimizer instead of the intended SafeReflectiveOptimizer, leading to intermittent script failures. 2. MethodAccessor coercion: methods with ExecutionContext parameter (e.g. bytesToExecutionArrayList) failed on re-execution because the coercion fallback path did not handle ExecutionContext injection. Also add @RepeatedTest for parseBytes_Test to verify stability. Co-Authored-By: Claude Opus 4.6 --- .../service/script/TbelInvokeDocsIoTest.java | 34 ++++++++++--------- pom.xml | 3 +- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java b/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java index 67e4ba8f32..9a3421b219 100644 --- a/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java +++ b/application/src/test/java/org/thingsboard/server/service/script/TbelInvokeDocsIoTest.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.service.script; +import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.Test; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.script.api.tbel.TbDate; @@ -779,7 +780,7 @@ class TbelInvokeDocsIoTest extends AbstractTbelInvokeTest { assertEquals(expected.toString(), actual.toString()); } - @Test + @Test public void setsCreateNewSetFromCreateSetTbMethod_Test() throws ExecutionException, InterruptedException { msgStr = """ {"list": ["B", "A", "C", "A"]} @@ -800,7 +801,7 @@ class TbelInvokeDocsIoTest extends AbstractTbelInvokeTest { assertEquals(expected.toString(), actual.toString()); } - @Test + @Test public void setsForeachForLoop_Test() throws ExecutionException, InterruptedException { msgStr = """ {"list": ["A", "B", "C"]} @@ -975,13 +976,13 @@ class TbelInvokeDocsIoTest extends AbstractTbelInvokeTest { ArrayList listSortDesc = new ArrayList<>(List.of("hello", "C", "B", "A", 34567, 34)); Set expectedDesc = new LinkedHashSet<>(listSortDesc); Object actual = invokeScript(evalScript(decoderStr), msgStr); - assertEquals(expectedAsc.toString(), ((LinkedHashMap)actual).get("set1").toString()); - assertEquals(expectedAsc.toString(), ((LinkedHashMap)actual).get("set1_asc").toString()); - assertEquals(expectedDesc.toString(), ((LinkedHashMap)actual).get("set1_desc").toString()); - assertEquals(expected.toString(), ((LinkedHashMap)actual).get("set2").toString()); - assertEquals(expectedAsc.toString(), ((LinkedHashMap)actual).get("set3").toString()); - assertEquals(expectedAsc.toString(), ((LinkedHashMap)actual).get("set3_asc").toString()); - assertEquals(expectedDesc.toString(), ((LinkedHashMap)actual).get("set3_desc").toString()); + assertEquals(expectedAsc.toString(), ((LinkedHashMap) actual).get("set1").toString()); + assertEquals(expectedAsc.toString(), ((LinkedHashMap) actual).get("set1_asc").toString()); + assertEquals(expectedDesc.toString(), ((LinkedHashMap) actual).get("set1_desc").toString()); + assertEquals(expected.toString(), ((LinkedHashMap) actual).get("set2").toString()); + assertEquals(expectedAsc.toString(), ((LinkedHashMap) actual).get("set3").toString()); + assertEquals(expectedAsc.toString(), ((LinkedHashMap) actual).get("set3_asc").toString()); + assertEquals(expectedDesc.toString(), ((LinkedHashMap) actual).get("set3_desc").toString()); } @Test @@ -1002,9 +1003,9 @@ class TbelInvokeDocsIoTest extends AbstractTbelInvokeTest { List listOrigin = new ArrayList<>(List.of("C", "B", "A", 34567, "B", "C", "hello", 34)); Set expectedSet = new LinkedHashSet<>(listOrigin); Object actual = invokeScript(evalScript(decoderStr), msgStr); - assertEquals(expectedSet.toString(), ((LinkedHashMap)actual).get("set1").toString()); - assertEquals(true, ((LinkedHashMap)actual).get("result1")); - assertEquals(false, ((LinkedHashMap)actual).get("result2")); + assertEquals(expectedSet.toString(), ((LinkedHashMap) actual).get("set1").toString()); + assertEquals(true, ((LinkedHashMap) actual).get("result1")); + assertEquals(false, ((LinkedHashMap) actual).get("result2")); } @Test @@ -1025,9 +1026,9 @@ class TbelInvokeDocsIoTest extends AbstractTbelInvokeTest { Set expectedSet = new LinkedHashSet<>(listOrigin); List expectedToList = new ArrayList<>(expectedSet); Object actual = invokeScript(evalScript(decoderStr), msgStr); - assertEquals(listOrigin.toString(), ((LinkedHashMap)actual).get("list").toString()); - assertEquals(expectedSet.toString(), ((LinkedHashMap)actual).get("set1").toString()); - assertEquals(expectedToList.toString(), ((LinkedHashMap)actual).get("tolist").toString()); + assertEquals(listOrigin.toString(), ((LinkedHashMap) actual).get("list").toString()); + assertEquals(expectedSet.toString(), ((LinkedHashMap) actual).get("set1").toString()); + assertEquals(expectedToList.toString(), ((LinkedHashMap) actual).get("tolist").toString()); } @Test @@ -1713,7 +1714,7 @@ class TbelInvokeDocsIoTest extends AbstractTbelInvokeTest { assertEquals(expected, actual); } - @Test + @RepeatedTest(value = 3, name = "{displayName} {currentRepetition}/{totalRepetitions}") public void parseBytes_Test() throws ExecutionException, InterruptedException { byte[] bytesExecutionArrayList = new byte[]{(byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD}; msgStr = "{}"; @@ -2821,5 +2822,6 @@ class TbelInvokeDocsIoTest extends AbstractTbelInvokeTest { } return list; } + } diff --git a/pom.xml b/pom.xml index b69540231e..a28a5ff6ab 100755 --- a/pom.xml +++ b/pom.xml @@ -64,7 +64,7 @@ 3.9.3 3.25.5 1.76.0 - 1.2.8 + 1.2.9 1.18.38 1.2.5 1.2.5 @@ -837,6 +837,7 @@ **/test/resources/lwm2m/** **/resources/lwm2m/models/** src/main/data/resources/** + .claude/** JAVADOC_STYLE