From eaf06daf6f19e643658c85a2874910a0824e4304 Mon Sep 17 00:00:00 2001 From: Emmanuel GALLOIS Date: Thu, 7 May 2026 17:58:38 +0200 Subject: [PATCH] fix(QTDI-2856): fix RegExp loading via SPI --- .../form/internal/validation/JavascriptRegex.java | 12 ++++++++++++ .../runtime/manager/reflect/ReflectionService.java | 13 +++++++++++++ 2 files changed, 25 insertions(+) diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/JavascriptRegex.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/JavascriptRegex.java index 4eff67920014b..66839b8b4750a 100644 --- a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/JavascriptRegex.java +++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/JavascriptRegex.java @@ -15,9 +15,12 @@ */ package org.talend.sdk.component.form.internal.validation; +import java.util.ServiceLoader; import java.util.function.Predicate; import org.mozilla.javascript.Context; +import org.mozilla.javascript.RegExpLoader; +import org.mozilla.javascript.ScriptRuntime; import org.mozilla.javascript.Scriptable; public class JavascriptRegex implements Predicate { @@ -47,6 +50,15 @@ public boolean test(final CharSequence text) { final String script = "new RegExp(regex, indicators).test(text)"; final Context context = Context.enter(); try { + // Rhino 1.9.0+: RegExp is registered via ServiceLoader. + // The ServiceLoader uses Thread.currentThread().getContextClassLoader() by default, + // which may not find the service in an isolated classloader context. + // Explicitly register RegExpProxy using Rhino's own classloader as fallback. + if (ScriptRuntime.getRegExpProxy(context) == null) { + ServiceLoader.load(RegExpLoader.class, context.getClass().getClassLoader()) + .findFirst() + .ifPresent(loader -> ScriptRuntime.setRegExpProxy(context, loader.newProxy())); + } final Scriptable scope = context.initStandardObjects(); scope.put("text", scope, text); scope.put("regex", scope, regex); diff --git a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/reflect/ReflectionService.java b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/reflect/ReflectionService.java index cb8b313a95757..cbc46f55ad124 100644 --- a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/reflect/ReflectionService.java +++ b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/reflect/ReflectionService.java @@ -44,6 +44,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.ServiceLoader; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -69,6 +70,8 @@ import org.apache.xbean.recipe.ObjectRecipe; import org.apache.xbean.recipe.UnsetPropertiesRecipe; import org.mozilla.javascript.Context; +import org.mozilla.javascript.RegExpLoader; +import org.mozilla.javascript.ScriptRuntime; import org.mozilla.javascript.Scriptable; import org.talend.sdk.component.api.record.Schema; import org.talend.sdk.component.api.service.configuration.Configuration; @@ -855,6 +858,16 @@ public boolean test(final CharSequence text) { final String script = "new RegExp(regex, indicators).test(text)"; final Context context = Context.enter(); try { + // Rhino 1.9.0+: RegExp is registered via ServiceLoader. + // The ServiceLoader uses Thread.currentThread().getContextClassLoader() by default, + // which may not find the service in an isolated classloader context. + // Explicitly register RegExpProxy using Rhino's own classloader as fallback. + if (ScriptRuntime.getRegExpProxy(context) == null) { + ServiceLoader + .load(RegExpLoader.class, context.getClass().getClassLoader()) + .findFirst() + .ifPresent(loader -> ScriptRuntime.setRegExpProxy(context, loader.newProxy())); + } final Scriptable scope = context.initStandardObjects(); scope.put("text", scope, text); scope.put("regex", scope, regex);