From 953054fadc8d25ddfddb500a355eaf3e70afa648 Mon Sep 17 00:00:00 2001 From: VoBa Date: Fri, 5 Mar 2021 18:18:58 +0200 Subject: [PATCH] eval is not thread safe. Added lock to avoid 'No such function invokeInternalXXX' exception (#4211) * eval is not thread safe. Added lock to avoid 'No such function invokeInternalXXX' exception * License fix --- .../script/AbstractNashornJsInvokeService.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/service/script/AbstractNashornJsInvokeService.java b/application/src/main/java/org/thingsboard/server/service/script/AbstractNashornJsInvokeService.java index 1d7a5d9533..f581145907 100644 --- a/application/src/main/java/org/thingsboard/server/service/script/AbstractNashornJsInvokeService.java +++ b/application/src/main/java/org/thingsboard/server/service/script/AbstractNashornJsInvokeService.java @@ -40,6 +40,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.ReentrantLock; @Slf4j public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeService { @@ -56,6 +57,8 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer private final FutureCallback evalCallback = new JsStatCallback<>(jsEvalMsgs, jsTimeoutMsgs, jsFailedMsgs); private final FutureCallback invokeCallback = new JsStatCallback<>(jsInvokeMsgs, jsTimeoutMsgs, jsFailedMsgs); + private final ReentrantLock evalLock = new ReentrantLock(); + @Getter private final JsExecutorService jsExecutor; @@ -121,10 +124,15 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer jsPushedMsgs.incrementAndGet(); ListenableFuture result = jsExecutor.executeAsync(() -> { try { - if (useJsSandbox()) { - sandbox.eval(jsScript); - } else { - engine.eval(jsScript); + evalLock.lock(); + try { + if (useJsSandbox()) { + sandbox.eval(jsScript); + } else { + engine.eval(jsScript); + } + } finally { + evalLock.unlock(); } scriptIdToNameMap.put(scriptId, functionName); return scriptId;