diff --git a/.gitignore b/.gitignore
index b6dbe45b555a1..a9b41ff6d1c1f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -74,3 +74,4 @@ documentation/rebuildpdf.bat
.claude/CLAUDE.md
.github/copilot-instructions.md
.claude/settings.json
+.ai-commons/skills/manage-zephyr-test-cases/scripts/.env
diff --git a/build/ExtractAsPropTypes.groovy b/build/ExtractAsPropTypes.groovy
index 02ae165bda453..938f2bdaac5d1 100644
--- a/build/ExtractAsPropTypes.groovy
+++ b/build/ExtractAsPropTypes.groovy
@@ -16,7 +16,7 @@
import java.lang.reflect.ParameterizedType
-import javax.json.bind.annotation.JsonbTransient
+import jakarta.json.bind.annotation.JsonbTransient
import static java.util.Locale.ROOT
import static java.util.Optional.ofNullable
@@ -99,7 +99,7 @@ GenerationAggregator createPropType(parent, clazz, aggregate) {
writer.write('const definition = {\n')
clazz.declaredFields.findAll { !it.isAnnotationPresent(JsonbTransient.class) }.sort { it.name }.each {
def type = it.genericType
- def name = ofNullable(it.getAnnotation(javax.json.bind.annotation.JsonbProperty.class))
+ def name = ofNullable(it.getAnnotation(jakarta.json.bind.annotation.JsonbProperty.class))
.map { t -> t.value() }.orElse(it.name)
if (ParameterizedType.class.isInstance(it.genericType)) {
if (Collection.class.isAssignableFrom(type.rawType)) {
diff --git a/component-api/pom.xml b/component-api/pom.xml
index 24d1d9567de95..88fb110fc70b2 100644
--- a/component-api/pom.xml
+++ b/component-api/pom.xml
@@ -32,24 +32,27 @@
+
- org.apache.geronimo.specs
- geronimo-annotation_1.3_spec
- ${geronimo-annotation.version}
+ jakarta.annotation
+ jakarta.annotation-api
- org.apache.geronimo.specs
- geronimo-json_1.1_spec
- ${geronimo-json.version}
+ jakarta.json
+ jakarta.json-api
- org.apache.geronimo.specs
- geronimo-jsonb_1.0_spec
- ${geronimo-jsonb.version}
+ jakarta.json.bind
+ jakarta.json.bind-api
org.apache.johnzon
johnzon-jsonb
+ ${johnzon.version}
test
diff --git a/component-api/src/main/java/org/talend/sdk/component/api/exception/DiscoverSchemaException.java b/component-api/src/main/java/org/talend/sdk/component/api/exception/DiscoverSchemaException.java
index a913307ac4c10..ec79f506681c9 100644
--- a/component-api/src/main/java/org/talend/sdk/component/api/exception/DiscoverSchemaException.java
+++ b/component-api/src/main/java/org/talend/sdk/component/api/exception/DiscoverSchemaException.java
@@ -15,8 +15,8 @@
*/
package org.talend.sdk.component.api.exception;
-import javax.json.bind.annotation.JsonbCreator;
-import javax.json.bind.annotation.JsonbPropertyOrder;
+import jakarta.json.bind.annotation.JsonbCreator;
+import jakarta.json.bind.annotation.JsonbPropertyOrder;
import lombok.Data;
import lombok.EqualsAndHashCode;
diff --git a/component-api/src/main/java/org/talend/sdk/component/api/record/Schema.java b/component-api/src/main/java/org/talend/sdk/component/api/record/Schema.java
index 3614fee11a25e..c72fc0d43f26a 100644
--- a/component-api/src/main/java/org/talend/sdk/component/api/record/Schema.java
+++ b/component-api/src/main/java/org/talend/sdk/component/api/record/Schema.java
@@ -31,10 +31,10 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import javax.json.Json;
-import javax.json.JsonValue;
-import javax.json.bind.annotation.JsonbTransient;
-import javax.json.stream.JsonParser;
+import jakarta.json.Json;
+import jakarta.json.JsonValue;
+import jakarta.json.bind.annotation.JsonbTransient;
+import jakarta.json.stream.JsonParser;
import lombok.EqualsAndHashCode;
import lombok.RequiredArgsConstructor;
@@ -69,6 +69,7 @@ public interface Schema {
/**
* @return All entries, including data and metadata, of this schema.
*/
+ @JsonbTransient
Stream getAllEntries();
@JsonbTransient
@@ -211,6 +212,7 @@ interface Entry {
/**
* @return the raw name of this entry if exists, else return name.
*/
+ @JsonbTransient
String getOriginalFieldName();
/**
diff --git a/component-api/src/main/java/org/talend/sdk/component/api/service/schema/Schema.java b/component-api/src/main/java/org/talend/sdk/component/api/service/schema/Schema.java
index e1b15b9581b14..97f5c09b28078 100644
--- a/component-api/src/main/java/org/talend/sdk/component/api/service/schema/Schema.java
+++ b/component-api/src/main/java/org/talend/sdk/component/api/service/schema/Schema.java
@@ -23,7 +23,7 @@
import java.util.Optional;
import java.util.stream.Stream;
-import javax.json.bind.annotation.JsonbTransient;
+import jakarta.json.bind.annotation.JsonbTransient;
import org.talend.sdk.component.api.meta.Partial;
diff --git a/component-api/src/test/java/org/talend/sdk/component/api/record/SchemaTest.java b/component-api/src/test/java/org/talend/sdk/component/api/record/SchemaTest.java
index 5d8c910fa4579..5969c9f178472 100644
--- a/component-api/src/test/java/org/talend/sdk/component/api/record/SchemaTest.java
+++ b/component-api/src/test/java/org/talend/sdk/component/api/record/SchemaTest.java
@@ -30,10 +30,10 @@
import java.util.Optional;
import java.util.stream.Stream;
-import javax.json.Json;
-import javax.json.JsonString;
-import javax.json.JsonValue;
-import javax.json.JsonValue.ValueType;
+import jakarta.json.Json;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
+import jakarta.json.JsonValue.ValueType;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
diff --git a/component-form/component-form-core/pom.xml b/component-form/component-form-core/pom.xml
index ba835c9d155ab..81a9148b51148 100644
--- a/component-form/component-form-core/pom.xml
+++ b/component-form/component-form-core/pom.xml
@@ -36,15 +36,15 @@
org.slf4j
slf4j-api
+
- org.apache.geronimo.specs
- geronimo-json_1.1_spec
- ${geronimo-json.version}
+ jakarta.json
+ jakarta.json-api
- org.apache.geronimo.specs
- geronimo-jsonb_1.0_spec
- ${geronimo-jsonb.version}
+ jakarta.json.bind
+ jakarta.json.bind-api
org.talend.sdk.component
@@ -57,12 +57,11 @@
${project.version}
-
-
- org.apache.johnzon
- johnzon-jsonschema
- ${johnzon.version}
-
+
org.mozilla
rhino
@@ -79,6 +78,7 @@
org.apache.johnzon
johnzon-jsonb
+ ${johnzon.version}
test
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/api/UiSpecService.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/api/UiSpecService.java
index e85d070d55d42..b53f720032e9c 100644
--- a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/api/UiSpecService.java
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/api/UiSpecService.java
@@ -28,9 +28,9 @@
import java.util.function.Predicate;
import java.util.function.Supplier;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
-import javax.json.bind.JsonbConfig;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.bind.JsonbConfig;
import org.talend.sdk.component.form.internal.converter.CustomPropertyConverter;
import org.talend.sdk.component.form.internal.converter.PropertyContext;
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/converter/impl/JsonSchemaConverter.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/converter/impl/JsonSchemaConverter.java
index 5c8c510f66e00..3117c84f42b34 100644
--- a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/converter/impl/JsonSchemaConverter.java
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/converter/impl/JsonSchemaConverter.java
@@ -32,7 +32,7 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
-import javax.json.bind.Jsonb;
+import jakarta.json.bind.Jsonb;
import org.talend.sdk.component.form.internal.converter.PropertyContext;
import org.talend.sdk.component.form.internal.converter.PropertyConverter;
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/converter/impl/PropertiesConverter.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/converter/impl/PropertiesConverter.java
index 956bccb1f4a5c..447ae15edcef1 100644
--- a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/converter/impl/PropertiesConverter.java
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/converter/impl/PropertiesConverter.java
@@ -23,7 +23,7 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
-import javax.json.bind.Jsonb;
+import jakarta.json.bind.Jsonb;
import org.talend.sdk.component.form.internal.converter.PropertyContext;
import org.talend.sdk.component.form.internal.converter.PropertyConverter;
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/converter/impl/schema/ArrayPropertyConverter.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/converter/impl/schema/ArrayPropertyConverter.java
index e480507356519..b778013cf5a6c 100644
--- a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/converter/impl/schema/ArrayPropertyConverter.java
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/converter/impl/schema/ArrayPropertyConverter.java
@@ -23,7 +23,7 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
-import javax.json.bind.Jsonb;
+import jakarta.json.bind.Jsonb;
import org.talend.sdk.component.form.internal.converter.PropertyContext;
import org.talend.sdk.component.form.internal.converter.PropertyConverter;
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/JsonSchemaValidatorFactoryExt.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/JsonSchemaValidatorFactoryExt.java
index 3894222f156be..115fd4b0e163e 100644
--- a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/JsonSchemaValidatorFactoryExt.java
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/JsonSchemaValidatorFactoryExt.java
@@ -21,15 +21,16 @@
import java.util.function.Predicate;
import java.util.stream.Collectors;
-import org.apache.johnzon.jsonschema.regex.JavaRegex;
-import org.apache.johnzon.jsonschema.spi.builtin.PatternValidation;
+import org.talend.sdk.component.form.internal.validation.jsonschema.regex.JavaRegex;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.PatternValidation;
import org.talend.sdk.component.form.internal.validation.spi.ext.EnumValidationWithDefaultValue;
import org.talend.sdk.component.form.internal.validation.spi.ext.MaximumValidation;
import org.talend.sdk.component.form.internal.validation.spi.ext.MinimumValidation;
import org.talend.sdk.component.form.internal.validation.spi.ext.RequiredValidation;
import org.talend.sdk.component.form.internal.validation.spi.ext.TypeValidation;
-public class JsonSchemaValidatorFactoryExt extends org.apache.johnzon.jsonschema.JsonSchemaValidatorFactory {
+public class JsonSchemaValidatorFactoryExt
+ extends org.talend.sdk.component.form.internal.validation.jsonschema.JsonSchemaValidatorFactory {
private final AtomicReference>> reFactory =
new AtomicReference<>(this::newRegexFactory);
@@ -39,14 +40,15 @@ public JsonSchemaValidatorFactoryExt() {
}
@Override
- public List createDefaultValidations() {
+ public List
+ createDefaultValidations() {
List validations = super.createDefaultValidations()
.stream()
- .filter(v -> !(v instanceof org.apache.johnzon.jsonschema.spi.builtin.TypeValidation))
- .filter(v -> !(v instanceof org.apache.johnzon.jsonschema.spi.builtin.EnumValidation))
- .filter(v -> !(v instanceof org.apache.johnzon.jsonschema.spi.builtin.MinimumValidation))
- .filter(v -> !(v instanceof org.apache.johnzon.jsonschema.spi.builtin.MaximumValidation))
- .filter(v -> !(v instanceof org.apache.johnzon.jsonschema.spi.builtin.RequiredValidation))
+ .filter(v -> !(v instanceof org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.TypeValidation))
+ .filter(v -> !(v instanceof org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.EnumValidation))
+ .filter(v -> !(v instanceof org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.MinimumValidation))
+ .filter(v -> !(v instanceof org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.MaximumValidation))
+ .filter(v -> !(v instanceof org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.RequiredValidation))
.filter(v -> !(v instanceof PatternValidation))
.collect(Collectors.toList());
validations.add(new TypeValidation());
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/JsonSchemaValidator.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/JsonSchemaValidator.java
new file mode 100644
index 0000000000000..d3b1e183acda9
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/JsonSchemaValidator.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema;
+
+import static java.util.Collections.emptyList;
+
+import java.util.Collection;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonValue;
+
+public class JsonSchemaValidator implements Function, AutoCloseable {
+
+ private static final ValidationResult SUCCESS = new ValidationResult(emptyList());
+
+ private final Function> validationFunction;
+
+ JsonSchemaValidator(final Function> validationFunction) {
+ this.validationFunction = validationFunction;
+ }
+
+ @Override
+ public ValidationResult apply(final JsonValue object) {
+ final Collection errors = validationFunction.apply(object).toList();
+ if (!errors.isEmpty()) {
+ return new ValidationResult(errors);
+ }
+ return SUCCESS;
+ }
+
+ @Override
+ public void close() {
+ // no-op
+ }
+
+ @Override
+ public String toString() {
+ return "JsonSchemaValidator{" +
+ "validationFunction=" + validationFunction +
+ '}';
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/JsonSchemaValidatorFactory.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/JsonSchemaValidatorFactory.java
new file mode 100644
index 0000000000000..2c7adb69d1f28
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/JsonSchemaValidatorFactory.java
@@ -0,0 +1,338 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema;
+
+import static java.util.Arrays.asList;
+import static java.util.Optional.ofNullable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.ServiceLoader;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import jakarta.json.JsonObject;
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.regex.JavaRegex;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.ContainsValidation;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.EnumValidation;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.ExclusiveMaximumValidation;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.ExclusiveMinimumValidation;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.IntegerValidation;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.ItemsValidation;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.MaxItemsValidation;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.MaxLengthValidation;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.MaxPropertiesValidation;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.MaximumValidation;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.MinItemsValidation;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.MinLengthValidation;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.MinPropertiesValidation;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.MinimumValidation;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.MultipleOfValidation;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.PatternValidation;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.RequiredValidation;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.TypeValidation;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.UniqueItemsValidation;
+
+public class JsonSchemaValidatorFactory implements AutoCloseable {
+
+ private static final String[] ROOT_PATH = new String[0];
+
+ private static final String PROPERTIES = "properties";
+
+ private static final String PATTERN_PROPERTIES = "patternProperties";
+
+ private static final Function> NO_VALIDATION =
+ new Function>() {
+
+ @Override
+ public Stream apply(final JsonValue jsonValue) {
+ return Stream.empty();
+ }
+
+ @Override
+ public String toString() {
+ return "NoValidation";
+ }
+ };
+
+ private final List extensions = new ArrayList<>();
+
+ // QTDI-3497 (experimental, jakarta-only spike): upstream tried a Nashorn-based JavascriptRegex
+ // first, falling back to JavaRegex only if that failed. Nashorn was removed from the JDK (JDK 15+),
+ // so on this JDK17-only codebase that fallback always won anyway; the JS engine variant wasn't
+ // ported (it also depended on the JDK-native javax.script API, out of scope for this migration).
+ private final AtomicReference>> regexFactory =
+ new AtomicReference<>(this::newRegexFactory);
+
+ private Predicate newRegexFactory(final String regex) {
+ return new JavaRegex(regex);
+ }
+
+ public JsonSchemaValidatorFactory() {
+ extensions.addAll(createDefaultValidations());
+ extensions.addAll(StreamSupport.stream(ServiceLoader.load(ValidationExtension.class).spliterator(), false)
+ .toList());
+ }
+
+ // see http://json-schema.org/latest/json-schema-validation.html
+ public List createDefaultValidations() {
+ return asList(
+ new RequiredValidation(),
+ new TypeValidation(),
+ new IntegerValidation(),
+ new EnumValidation(),
+ new MultipleOfValidation(),
+ new MaximumValidation(),
+ new MinimumValidation(),
+ new ExclusiveMaximumValidation(),
+ new ExclusiveMinimumValidation(),
+ new MaxLengthValidation(),
+ new MinLengthValidation(),
+ new PatternValidation(regexFactory.get()),
+ new ItemsValidation(this),
+ new MaxItemsValidation(),
+ new MinItemsValidation(),
+ new UniqueItemsValidation(),
+ new ContainsValidation(this),
+ new MaxPropertiesValidation(),
+ new MinPropertiesValidation());
+ // not supported yet: dependencies, propertyNames, if/then/else, allOf/anyOf/oneOf/not, format validations
+ }
+
+ public JsonSchemaValidatorFactory appendExtensions(final ValidationExtension... extensions) {
+ this.extensions.addAll(asList(extensions));
+ return this;
+ }
+
+ public JsonSchemaValidatorFactory setExtensions(final ValidationExtension... extensions) {
+ this.extensions.clear();
+ return appendExtensions(extensions);
+ }
+
+ public JsonSchemaValidatorFactory setRegexFactory(final Function> factory) {
+ regexFactory.set(factory);
+ return this;
+ }
+
+ public JsonSchemaValidator newInstance(final JsonObject schema) {
+ return new JsonSchemaValidator(buildValidator(ROOT_PATH, schema, null));
+ }
+
+ @Override
+ public void close() {
+ // no-op for now
+ }
+
+ private Function> buildValidator(final String[] path,
+ final JsonObject schema,
+ final UnaryOperator valueProvider) {
+ final List>> directValidations =
+ buildDirectValidations(path, schema, valueProvider).toList();
+ final Function> nestedValidations =
+ buildPropertiesValidations(path, schema, valueProvider);
+ final Function> dynamicNestedValidations =
+ buildPatternPropertiesValidations(path, schema, valueProvider);
+ final Function> fallbackNestedValidations =
+ buildAdditionalPropertiesValidations(path, schema, valueProvider);
+ return new ValidationsFunction(
+ Stream.concat(
+ directValidations.stream(),
+ Stream.of(nestedValidations, dynamicNestedValidations, fallbackNestedValidations))
+ .toList());
+ }
+
+ private Stream>> buildDirectValidations(
+ final String[] path,
+ final JsonObject schema,
+ final UnaryOperator valueProvider) {
+ final ValidationContext model = new ValidationContext(path, schema, valueProvider);
+ return extensions.stream()
+ .map(e -> e.create(model))
+ .filter(Optional::isPresent)
+ .map(Optional::get);
+ }
+
+ private Function> buildPropertiesValidations(
+ final String[] path,
+ final JsonObject schema,
+ final UnaryOperator valueProvider) {
+ return ofNullable(schema.get(PROPERTIES))
+ .filter(it -> it.getValueType() == JsonValue.ValueType.OBJECT)
+ .map(it -> it.asJsonObject()
+ .entrySet()
+ .stream()
+ .filter(obj -> obj.getValue().getValueType() == JsonValue.ValueType.OBJECT)
+ .map(obj -> {
+ final String key = obj.getKey();
+ final String[] fieldPath =
+ Stream.concat(Stream.of(path), Stream.of(key)).toArray(String[]::new);
+ return buildValidator(fieldPath, obj.getValue().asJsonObject(),
+ new ChainedValueAccessor(valueProvider, key));
+ })
+ .toList())
+ .map(this::toFunction)
+ .orElse(NO_VALIDATION);
+ }
+
+ // not the best impl but is it really an important case?
+ private Function> buildPatternPropertiesValidations(
+ final String[] path,
+ final JsonObject schema,
+ final UnaryOperator valueProvider) {
+ return ofNullable(schema.get(PATTERN_PROPERTIES))
+ .filter(it -> it.getValueType() == JsonValue.ValueType.OBJECT)
+ .map(it -> it.asJsonObject()
+ .entrySet()
+ .stream()
+ .filter(obj -> obj.getValue().getValueType() == JsonValue.ValueType.OBJECT)
+ .map(obj -> {
+ final Predicate pattern = regexFactory.get().apply(obj.getKey());
+ final JsonObject currentSchema = obj.getValue().asJsonObject();
+ // no cache cause otherwise it could be in properties
+ return (Function>) root -> {
+ final JsonValue validable = Optional.ofNullable(valueProvider)
+ .map(provider -> provider.apply(root))
+ .orElse(root);
+ if (validable.getValueType() != JsonValue.ValueType.OBJECT) {
+ return Stream.empty();
+ }
+ return validable.asJsonObject()
+ .entrySet()
+ .stream()
+ .filter(e -> pattern.test(e.getKey()))
+ .flatMap(e -> buildValidator(
+ Stream.concat(Stream.of(path), Stream.of(e.getKey()))
+ .toArray(String[]::new),
+ currentSchema,
+ o -> o.asJsonObject().get(e.getKey()))
+ .apply(validable));
+ };
+ })
+ .toList())
+ .map(this::toFunction)
+ .orElse(NO_VALIDATION);
+ }
+
+ private Function> buildAdditionalPropertiesValidations(
+ final String[] path,
+ final JsonObject schema,
+ final UnaryOperator valueProvider) {
+ return ofNullable(schema.get("additionalProperties"))
+ .filter(it -> it.getValueType() == JsonValue.ValueType.OBJECT)
+ .map(it -> {
+ Predicate excluded = s -> false;
+ if (schema.containsKey(PROPERTIES)) {
+ final Set properties = schema.getJsonObject(PROPERTIES).keySet();
+ excluded = excluded.and(s -> !properties.contains(s));
+ }
+ if (schema.containsKey(PATTERN_PROPERTIES)) {
+ final List> properties = schema.getJsonObject(PATTERN_PROPERTIES)
+ .keySet()
+ .stream()
+ .map(regexFactory.get())
+ .toList();
+ excluded = excluded.and(s -> properties.stream().noneMatch(p -> p.test(s)));
+ }
+ final Predicate excludeAttrRef = excluded;
+ final JsonObject currentSchema = it.asJsonObject();
+ return (Function>) validable -> {
+ if (validable.getValueType() != JsonValue.ValueType.OBJECT) {
+ return Stream.empty();
+ }
+ return validable.asJsonObject()
+ .entrySet()
+ .stream()
+ .filter(e -> excludeAttrRef.test(e.getKey()))
+ .flatMap(e -> buildValidator(
+ Stream.concat(Stream.of(path), Stream.of(e.getKey())).toArray(String[]::new),
+ currentSchema,
+ new ChainedValueAccessor(valueProvider, e.getKey())).apply(validable));
+ };
+ })
+ .orElse(NO_VALIDATION);
+ }
+
+ private Function> toFunction(
+ final List>> validations) {
+ return new ValidationsFunction(validations);
+ }
+
+ private static class ValidationsFunction implements Function> {
+
+ private final List>> delegates;
+
+ private ValidationsFunction(
+ final List>> validations) {
+ // unwrap when possible to simplify the stack and make toString readable (debug)
+ this.delegates = validations.stream()
+ .flatMap(it -> it instanceof ValidationsFunction vf
+ ? vf.delegates.stream()
+ : Stream.of(it))
+ .filter(it -> it != NO_VALIDATION)
+ .toList();
+ }
+
+ @Override
+ public Stream apply(final JsonValue jsonValue) {
+ return delegates.stream().flatMap(v -> v.apply(jsonValue));
+ }
+
+ @Override
+ public String toString() {
+ return delegates.toString();
+ }
+ }
+
+ private static class ChainedValueAccessor implements UnaryOperator {
+
+ private final UnaryOperator parent;
+
+ private final String key;
+
+ private ChainedValueAccessor(final UnaryOperator valueProvider, final String key) {
+ this.parent = valueProvider;
+ this.key = key;
+ }
+
+ @Override
+ public JsonValue apply(final JsonValue value) {
+ final JsonValue root = parent == null ? value : parent.apply(value);
+ if (root != null && root.getValueType() != JsonValue.ValueType.NULL
+ && root.getValueType() == JsonValue.ValueType.OBJECT) {
+ return root.asJsonObject().get(key);
+ }
+ return JsonValue.NULL;
+ }
+
+ @Override
+ public String toString() {
+ return "ChainedValueAccessor{" +
+ "parent=" + parent +
+ ", key='" + key + '\'' +
+ '}';
+ }
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/ValidationResult.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/ValidationResult.java
new file mode 100644
index 0000000000000..ed9c9840b84d5
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/ValidationResult.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema;
+
+import java.util.Collection;
+
+public class ValidationResult {
+
+ private Collection errors;
+
+ public ValidationResult() {
+ // no-op
+ }
+
+ ValidationResult(final Collection errors) {
+ this.errors = errors;
+ }
+
+ public boolean isSuccess() {
+ return errors == null || errors.isEmpty();
+ }
+
+ public Collection getErrors() {
+ return errors;
+ }
+
+ public void setErrors(final Collection errors) {
+ this.errors = errors;
+ }
+
+ @Override
+ public String toString() {
+ return "ValidationResult{" +
+ "errors=" + errors +
+ '}';
+ }
+
+ public static class ValidationError {
+
+ private String field;
+
+ private String message;
+
+ public ValidationError() {
+ // no-op
+ }
+
+ public ValidationError(final String field, final String message) {
+ this.field = field;
+ this.message = message;
+ }
+
+ public String getField() {
+ return field;
+ }
+
+ public void setField(final String field) {
+ this.field = field;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(final String message) {
+ this.message = message;
+ }
+
+ @Override
+ public String toString() {
+ return "ValidationError{" +
+ "field='" + field + '\'' +
+ ", message='" + message + '\'' +
+ '}';
+ }
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/regex/JavaRegex.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/regex/JavaRegex.java
new file mode 100644
index 0000000000000..5caddd94a7ea0
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/regex/JavaRegex.java
@@ -0,0 +1,38 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.regex;
+
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+
+public class JavaRegex implements Predicate {
+
+ private final Pattern pattern;
+
+ public JavaRegex(final String pattern) {
+ this.pattern = Pattern.compile(pattern);
+ }
+
+ @Override
+ public boolean test(final CharSequence charSequence) {
+ return pattern.matcher(charSequence).matches();
+ }
+
+ @Override
+ public String toString() {
+ return "JavaRegex{" + pattern + '}';
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/ValidationContext.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/ValidationContext.java
new file mode 100644
index 0000000000000..4a490fced5b2e
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/ValidationContext.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi;
+
+import static java.util.stream.Collectors.joining;
+
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonObject;
+import jakarta.json.JsonValue;
+
+public class ValidationContext {
+
+ private final String[] path;
+
+ private final JsonObject schema;
+
+ private final UnaryOperator valueProvider;
+
+ public ValidationContext(final String[] path, final JsonObject schema,
+ final UnaryOperator valueProvider) {
+ this.path = path;
+ this.schema = schema;
+ this.valueProvider = valueProvider;
+ }
+
+ public UnaryOperator getValueProvider() {
+ return valueProvider;
+ }
+
+ public String[] getPath() {
+ return path;
+ }
+
+ public JsonObject getSchema() {
+ return schema;
+ }
+
+ public String toPointer() {
+ return Stream.of(path).collect(joining("/", "/", ""));
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/ValidationExtension.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/ValidationExtension.java
new file mode 100644
index 0000000000000..f33fdb27498aa
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/ValidationExtension.java
@@ -0,0 +1,29 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi;
+
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+
+public interface ValidationExtension {
+
+ Optional>> create(ValidationContext model);
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/BaseNumberValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/BaseNumberValidation.java
new file mode 100644
index 0000000000000..1a346be0c493e
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/BaseNumberValidation.java
@@ -0,0 +1,78 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+
+abstract class BaseNumberValidation extends BaseValidation {
+
+ protected final double bound;
+
+ private final String name;
+
+ BaseNumberValidation(final String name, final String pointer, final UnaryOperator extractor,
+ final double bound) {
+ super(pointer, extractor, JsonValue.ValueType.NUMBER);
+ this.name = name;
+ this.bound = bound;
+ }
+
+ @FunctionalInterface
+ interface Factory {
+
+ BaseNumberValidation create(String pointer, UnaryOperator extractor, double bound);
+ }
+
+ static Optional>> create(
+ final ValidationContext model, final String keyword, final Factory factory) {
+ if (!"number".equals(model.getSchema().getString("type", "object"))) {
+ return Optional.empty();
+ }
+ return Optional.ofNullable(model.getSchema().get(keyword))
+ .filter(v -> v
+ .getValueType() == JsonValue.ValueType.NUMBER).>> map(
+ m -> factory.create(model.toPointer(), model.getValueProvider(),
+ JsonNumber.class.cast(m).doubleValue()));
+ }
+
+ @Override
+ public String toString() {
+ return name + "{bound=" + bound + ", pointer='" + pointer + "'}";
+ }
+
+ @Override
+ protected Stream onNumber(final JsonNumber number) {
+ final double val = number.doubleValue();
+ if (isValid(val)) {
+ return Stream.empty();
+ }
+ return toError(val);
+ }
+
+ protected abstract boolean isValid(double val);
+
+ protected abstract Stream toError(double val);
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/BaseSizeValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/BaseSizeValidation.java
new file mode 100644
index 0000000000000..1d49785a6a469
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/BaseSizeValidation.java
@@ -0,0 +1,73 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+
+// shared base of the min/max length, items and properties validations
+abstract class BaseSizeValidation extends BaseValidation {
+
+ protected final int bound;
+
+ private final String name;
+
+ BaseSizeValidation(final String name, final String pointer, final UnaryOperator extractor,
+ final JsonValue.ValueType validType, final int bound) {
+ super(pointer, extractor, validType);
+ this.name = name;
+ this.bound = bound;
+ }
+
+ @FunctionalInterface
+ interface Factory {
+
+ BaseSizeValidation create(String pointer, UnaryOperator extractor, int bound);
+ }
+
+ // requiredSchemaType == null means the keyword applies whatever the schema type is
+ static Optional>> create(
+ final ValidationContext model, final String keyword, final String requiredSchemaType,
+ final Factory factory) {
+ if (requiredSchemaType != null
+ && !requiredSchemaType.equals(model.getSchema().getString("type", "object"))) {
+ return Optional.empty();
+ }
+ return Optional.ofNullable(model.getSchema().get(keyword))
+ .filter(it -> it.getValueType() == JsonValue.ValueType.NUMBER)
+ .map(it -> JsonNumber.class.cast(it).intValue())
+ .filter(it -> it >= 0).>> map(
+ value -> factory.create(model.toPointer(), model.getValueProvider(), value));
+ }
+
+ protected Stream error(final String message) {
+ return Stream.of(new ValidationResult.ValidationError(pointer, message));
+ }
+
+ @Override
+ public String toString() {
+ return name + "{bound=" + bound + ", pointer='" + pointer + "'}";
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/BaseValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/BaseValidation.java
new file mode 100644
index 0000000000000..8803ca6c8916b
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/BaseValidation.java
@@ -0,0 +1,106 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonArray;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+
+public abstract class BaseValidation implements Function> {
+
+ protected final String pointer;
+
+ protected final UnaryOperator extractor;
+
+ private final JsonValue.ValueType validType;
+
+ private final boolean rootCanBeNull;
+
+ protected BaseValidation(final String pointer, final UnaryOperator extractor,
+ final JsonValue.ValueType validType) {
+ this.pointer = pointer;
+ this.extractor = extractor != null ? extractor : v -> v;
+ this.rootCanBeNull = extractor != null;
+ this.validType = validType;
+ }
+
+ @Override
+ public Stream apply(final JsonValue obj) {
+ if (isNull(obj) && rootCanBeNull) {
+ return Stream.empty();
+ }
+
+ final JsonValue value = extractor.apply(obj);
+ if (value == null || JsonValue.ValueType.NULL == value.getValueType() || value.getValueType() != validType) {
+ return Stream.empty();
+ }
+
+ switch (value.getValueType()) {
+ case STRING:
+ return onString(JsonString.class.cast(value));
+ case TRUE, FALSE:
+ return onBoolean(JsonValue.ValueType.TRUE == value.getValueType());
+ case NUMBER:
+ return onNumber(JsonNumber.class.cast(value));
+ case OBJECT:
+ return onObject(value.asJsonObject());
+ case ARRAY:
+ return onArray(value.asJsonArray());
+ case NULL:
+ return Stream.empty();
+ default:
+ throw new IllegalArgumentException("Unsupported value type: " + value);
+ }
+ }
+
+ protected boolean isNull(final JsonValue obj) {
+ return null == obj || obj.getValueType() == JsonValue.ValueType.NULL;
+ }
+
+ // optional hooks, the parameters are meant to be used by the overriding implementations
+ @SuppressWarnings("java:S1172")
+ protected Stream onArray(final JsonArray array) {
+ return Stream.empty();
+ }
+
+ @SuppressWarnings("java:S1172")
+ protected Stream onObject(final JsonObject object) {
+ return Stream.empty();
+ }
+
+ @SuppressWarnings("java:S1172")
+ protected Stream onNumber(final JsonNumber number) {
+ return Stream.empty();
+ }
+
+ @SuppressWarnings("java:S1172")
+ protected Stream onBoolean(final boolean value) {
+ return Stream.empty();
+ }
+
+ @SuppressWarnings("java:S1172")
+ protected Stream onString(final JsonString cast) {
+ return Stream.empty();
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/ContainsValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/ContainsValidation.java
new file mode 100644
index 0000000000000..7703e23177686
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/ContainsValidation.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import java.util.Collection;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonArray;
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.JsonSchemaValidator;
+import org.talend.sdk.component.form.internal.validation.jsonschema.JsonSchemaValidatorFactory;
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
+
+public class ContainsValidation implements ValidationExtension {
+
+ private final JsonSchemaValidatorFactory factory;
+
+ public ContainsValidation(final JsonSchemaValidatorFactory factory) {
+ this.factory = factory;
+ }
+
+ @Override
+ public Optional>>
+ create(final ValidationContext model) {
+ return Optional.ofNullable(model.getSchema().get("contains"))
+ .filter(it -> it.getValueType() == JsonValue.ValueType.OBJECT)
+ .map(it -> new ItemsValidator(model.toPointer(), model.getValueProvider(),
+ factory.newInstance(it.asJsonObject())));
+ }
+
+ private static class ItemsValidator extends BaseValidation {
+
+ private final JsonSchemaValidator validator;
+
+ private ItemsValidator(final String pointer,
+ final UnaryOperator extractor,
+ final JsonSchemaValidator validator) {
+ super(pointer, extractor, JsonValue.ValueType.ARRAY);
+ this.validator = validator;
+ }
+
+ @Override
+ protected Stream onArray(final JsonArray array) {
+ for (final JsonValue value : array) {
+ final Collection itemErrors = validator.apply(value).getErrors();
+ if (itemErrors.isEmpty()) {
+ return Stream.empty();
+ }
+ }
+ return Stream.of(new ValidationResult.ValidationError(pointer, "No item matching the expected schema"));
+ }
+
+ @Override
+ public String toString() {
+ return "Contains{" +
+ "validator=" + validator +
+ ", pointer='" + pointer + '\'' +
+ '}';
+ }
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/EnumValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/EnumValidation.java
new file mode 100644
index 0000000000000..e836a9ee5af0e
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/EnumValidation.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import static java.util.Optional.ofNullable;
+
+import java.util.Collection;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
+
+public class EnumValidation implements ValidationExtension {
+
+ @Override
+ public Optional>>
+ create(final ValidationContext model) {
+ return ofNullable(model.getSchema().get("enum"))
+ .filter(it -> it.getValueType() == JsonValue.ValueType.ARRAY)
+ .map(JsonValue::asJsonArray)
+ .map(values -> new Impl(values, model.getValueProvider(), model.toPointer(),
+ JsonValue.TRUE.equals(model.getSchema().get("nullable"))));
+ }
+
+ private static class Impl extends BaseValidation {
+
+ private final Collection valid;
+
+ private final boolean nullable;
+
+ private Impl(final Collection valid, final UnaryOperator extractor,
+ final String pointer, final boolean nullable) {
+ super(pointer, extractor, JsonValue.ValueType.OBJECT /* ignored */);
+ this.valid = valid;
+ this.nullable = nullable;
+ }
+
+ @Override
+ public Stream apply(final JsonValue root) {
+ if (isNull(root)) {
+ return Stream.empty();
+ }
+ final JsonValue value = extractor.apply(root);
+ if (nullable && (value == null || JsonValue.ValueType.NULL == value.getValueType())) {
+ return Stream.empty();
+ }
+ if (valid.contains(value)) {
+ return Stream.empty();
+ }
+ return Stream.of(new ValidationResult.ValidationError(pointer,
+ "Invalid value, got " + value + ", expected: " + valid));
+ }
+
+ @Override
+ public String toString() {
+ return "Enum{" +
+ "valid=" + valid +
+ ", pointer='" + pointer + '\'' +
+ '}';
+ }
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/ExclusiveMaximumValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/ExclusiveMaximumValidation.java
new file mode 100644
index 0000000000000..f091b6884fd2b
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/ExclusiveMaximumValidation.java
@@ -0,0 +1,54 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
+
+public class ExclusiveMaximumValidation implements ValidationExtension {
+
+ @Override
+ public Optional>>
+ create(final ValidationContext model) {
+ return BaseNumberValidation.create(model, "exclusiveMaximum", Impl::new);
+ }
+
+ private static class Impl extends BaseNumberValidation {
+
+ private Impl(final String pointer, final UnaryOperator valueProvider, final double bound) {
+ super("ExclusiveMaximum", pointer, valueProvider, bound);
+ }
+
+ @Override
+ protected boolean isValid(final double val) {
+ return val < this.bound;
+ }
+
+ @Override
+ protected Stream toError(final double val) {
+ return Stream
+ .of(new ValidationResult.ValidationError(pointer, val + " is strictly more than " + this.bound));
+ }
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/ExclusiveMinimumValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/ExclusiveMinimumValidation.java
new file mode 100644
index 0000000000000..b7c78fb75c5d8
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/ExclusiveMinimumValidation.java
@@ -0,0 +1,54 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
+
+public class ExclusiveMinimumValidation implements ValidationExtension {
+
+ @Override
+ public Optional>>
+ create(final ValidationContext model) {
+ return BaseNumberValidation.create(model, "exclusiveMinimum", Impl::new);
+ }
+
+ private static class Impl extends BaseNumberValidation {
+
+ private Impl(final String pointer, final UnaryOperator valueProvider, final double bound) {
+ super("ExclusiveMinimum", pointer, valueProvider, bound);
+ }
+
+ @Override
+ protected boolean isValid(final double val) {
+ return val > this.bound;
+ }
+
+ @Override
+ protected Stream toError(final double val) {
+ return Stream
+ .of(new ValidationResult.ValidationError(pointer, val + " is strictly less than " + this.bound));
+ }
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/IntegerValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/IntegerValidation.java
new file mode 100644
index 0000000000000..a2b01afd80ea2
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/IntegerValidation.java
@@ -0,0 +1,41 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
+import jakarta.json.JsonValue.ValueType;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult.ValidationError;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
+
+public class IntegerValidation implements ValidationExtension {
+
+ @Override
+ public Optional>> create(final ValidationContext model) {
+ final JsonValue type = model.getSchema().get("type");
+ if (type.getValueType().equals(ValueType.STRING) && "integer".equals(JsonString.class.cast(type).getString())) {
+ return Optional.of(new MultipleOfValidation.Impl(model.toPointer(), model.getValueProvider(), 1));
+ }
+ return Optional.empty();
+ }
+
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/ItemsValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/ItemsValidation.java
new file mode 100644
index 0000000000000..195248d70d489
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/ItemsValidation.java
@@ -0,0 +1,108 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import static java.util.Collections.singleton;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonArray;
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.JsonSchemaValidator;
+import org.talend.sdk.component.form.internal.validation.jsonschema.JsonSchemaValidatorFactory;
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
+
+public class ItemsValidation implements ValidationExtension {
+
+ private final JsonSchemaValidatorFactory factory;
+
+ public ItemsValidation(final JsonSchemaValidatorFactory factory) {
+ this.factory = factory;
+ }
+
+ @Override
+ public Optional>>
+ create(final ValidationContext model) {
+ return Optional.ofNullable(model.getSchema().get("items"))
+ .map(items -> {
+ switch (items.getValueType()) {
+ case OBJECT:
+ final JsonSchemaValidator objectValidator = factory.newInstance(items.asJsonObject());
+ return new ItemsValidator(model.toPointer(), model.getValueProvider(),
+ singleton(objectValidator));
+ case ARRAY:
+ return new ItemsValidator(model.toPointer(), model.getValueProvider(),
+ items.asJsonArray()
+ .stream()
+ .filter(it -> it.getValueType() == JsonValue.ValueType.OBJECT)
+ .map(it -> factory.newInstance(it.asJsonObject()))
+ .toList());
+ default:
+ return null;
+ }
+ });
+ }
+
+ private static class ItemsValidator extends BaseValidation {
+
+ private final Collection objectValidators;
+
+ private ItemsValidator(final String pointer,
+ final UnaryOperator extractor,
+ final Collection objectValidators) {
+ super(pointer, extractor, JsonValue.ValueType.ARRAY);
+ this.objectValidators = objectValidators;
+ }
+
+ @Override
+ protected Stream onArray(final JsonArray array) {
+ Collection errors = null;
+ for (int i = 0; i < array.size(); i++) {
+ final JsonValue value = array.get(i);
+ final Collection itemErrors = objectValidators.stream()
+ .flatMap(validator -> validator.apply(value).getErrors().stream())
+ .toList();
+ if (itemErrors != null && !itemErrors.isEmpty()) {
+ if (errors == null) {
+ errors = new ArrayList<>();
+ }
+ final String suffix = "[" + i + "]";
+ errors.addAll(itemErrors.stream()
+ .map(e -> new ValidationResult.ValidationError(pointer + e.getField() + suffix,
+ e.getMessage()))
+ .toList());
+ }
+ }
+ return errors == null ? Stream.empty() : errors.stream();
+ }
+
+ @Override
+ public String toString() {
+ return "Items{" +
+ "validators=" + objectValidators +
+ ", pointer='" + pointer + '\'' +
+ '}';
+ }
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MaxItemsValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MaxItemsValidation.java
new file mode 100644
index 0000000000000..150038a5122bc
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MaxItemsValidation.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonArray;
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
+
+public class MaxItemsValidation implements ValidationExtension {
+
+ @Override
+ public Optional>>
+ create(final ValidationContext model) {
+ return BaseSizeValidation.create(model, "maxItems", null, Impl::new);
+ }
+
+ private static class Impl extends BaseSizeValidation {
+
+ private Impl(final String pointer, final UnaryOperator extractor, final int bound) {
+ super("MaxItems", pointer, extractor, JsonValue.ValueType.ARRAY, bound);
+ }
+
+ @Override
+ protected Stream onArray(final JsonArray array) {
+ return array.size() > bound ? error("Too much items in the array (> " + bound + ")") : Stream.empty();
+ }
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MaxLengthValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MaxLengthValidation.java
new file mode 100644
index 0000000000000..6c4570fc8ce55
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MaxLengthValidation.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
+
+public class MaxLengthValidation implements ValidationExtension {
+
+ @Override
+ public Optional>>
+ create(final ValidationContext model) {
+ return BaseSizeValidation.create(model, "maxLength", "string", Impl::new);
+ }
+
+ private static class Impl extends BaseSizeValidation {
+
+ private Impl(final String pointer, final UnaryOperator valueProvider, final int bound) {
+ super("MaxLength", pointer, valueProvider, JsonValue.ValueType.STRING, bound);
+ }
+
+ @Override
+ protected Stream onString(final JsonString val) {
+ return val.getString().length() > bound ? error(val + " length is more than " + bound) : Stream.empty();
+ }
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MaxPropertiesValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MaxPropertiesValidation.java
new file mode 100644
index 0000000000000..9f6aeccd6c7c7
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MaxPropertiesValidation.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonObject;
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
+
+public class MaxPropertiesValidation implements ValidationExtension {
+
+ @Override
+ public Optional>>
+ create(final ValidationContext model) {
+ return BaseSizeValidation.create(model, "maxProperties", null, Impl::new);
+ }
+
+ private static class Impl extends BaseSizeValidation {
+
+ private Impl(final String pointer, final UnaryOperator extractor, final int bound) {
+ super("MaxProperties", pointer, extractor, JsonValue.ValueType.OBJECT, bound);
+ }
+
+ @Override
+ protected Stream onObject(final JsonObject object) {
+ return object.size() > bound ? error("Too much properties (> " + bound + ")") : Stream.empty();
+ }
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MaximumValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MaximumValidation.java
new file mode 100644
index 0000000000000..b3a0764ce07a8
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MaximumValidation.java
@@ -0,0 +1,53 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
+
+public class MaximumValidation implements ValidationExtension {
+
+ @Override
+ public Optional>>
+ create(final ValidationContext model) {
+ return BaseNumberValidation.create(model, "maximum", Impl::new);
+ }
+
+ private static class Impl extends BaseNumberValidation {
+
+ private Impl(final String pointer, final UnaryOperator valueProvider, final double bound) {
+ super("Maximum", pointer, valueProvider, bound);
+ }
+
+ @Override
+ protected boolean isValid(final double val) {
+ return val <= this.bound;
+ }
+
+ @Override
+ protected Stream toError(final double val) {
+ return Stream.of(new ValidationResult.ValidationError(pointer, val + " is more than " + this.bound));
+ }
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MinItemsValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MinItemsValidation.java
new file mode 100644
index 0000000000000..f3ebffa036bf2
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MinItemsValidation.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonArray;
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
+
+public class MinItemsValidation implements ValidationExtension {
+
+ @Override
+ public Optional>>
+ create(final ValidationContext model) {
+ return BaseSizeValidation.create(model, "minItems", null, Impl::new);
+ }
+
+ private static class Impl extends BaseSizeValidation {
+
+ private Impl(final String pointer, final UnaryOperator extractor, final int bound) {
+ super("MinItems", pointer, extractor, JsonValue.ValueType.ARRAY, bound);
+ }
+
+ @Override
+ protected Stream onArray(final JsonArray array) {
+ return array.size() < bound ? error("Not enough items in the array (< " + bound + ")") : Stream.empty();
+ }
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MinLengthValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MinLengthValidation.java
new file mode 100644
index 0000000000000..a8d0d48de19ad
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MinLengthValidation.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
+
+public class MinLengthValidation implements ValidationExtension {
+
+ @Override
+ public Optional>>
+ create(final ValidationContext model) {
+ return BaseSizeValidation.create(model, "minLength", "string", Impl::new);
+ }
+
+ private static class Impl extends BaseSizeValidation {
+
+ private Impl(final String pointer, final UnaryOperator valueProvider, final int bound) {
+ super("MinLength", pointer, valueProvider, JsonValue.ValueType.STRING, bound);
+ }
+
+ @Override
+ protected Stream onString(final JsonString val) {
+ return val.getString().length() < bound ? error(val + " length is less than " + bound) : Stream.empty();
+ }
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MinPropertiesValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MinPropertiesValidation.java
new file mode 100644
index 0000000000000..818e3baaeb2ac
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MinPropertiesValidation.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonObject;
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
+
+public class MinPropertiesValidation implements ValidationExtension {
+
+ @Override
+ public Optional>>
+ create(final ValidationContext model) {
+ return BaseSizeValidation.create(model, "minProperties", null, Impl::new);
+ }
+
+ private static class Impl extends BaseSizeValidation {
+
+ private Impl(final String pointer, final UnaryOperator extractor, final int bound) {
+ super("MinProperties", pointer, extractor, JsonValue.ValueType.OBJECT, bound);
+ }
+
+ @Override
+ protected Stream onObject(final JsonObject object) {
+ return object.size() < bound ? error("Not enough properties (> " + bound + ")") : Stream.empty();
+ }
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MinimumValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MinimumValidation.java
new file mode 100644
index 0000000000000..2d31d3295cfb0
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MinimumValidation.java
@@ -0,0 +1,53 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
+
+public class MinimumValidation implements ValidationExtension {
+
+ @Override
+ public Optional>>
+ create(final ValidationContext model) {
+ return BaseNumberValidation.create(model, "minimum", Impl::new);
+ }
+
+ private static class Impl extends BaseNumberValidation {
+
+ private Impl(final String pointer, final UnaryOperator valueProvider, final double bound) {
+ super("Minimum", pointer, valueProvider, bound);
+ }
+
+ @Override
+ protected boolean isValid(final double val) {
+ return val >= this.bound;
+ }
+
+ @Override
+ protected Stream toError(final double val) {
+ return Stream.of(new ValidationResult.ValidationError(pointer, val + " is less than " + this.bound));
+ }
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MultipleOfValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MultipleOfValidation.java
new file mode 100644
index 0000000000000..d4b4589fb9f40
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/MultipleOfValidation.java
@@ -0,0 +1,54 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
+
+public class MultipleOfValidation implements ValidationExtension {
+
+ @Override
+ public Optional>>
+ create(final ValidationContext model) {
+ return BaseNumberValidation.create(model, "multipleOf", Impl::new);
+ }
+
+ static class Impl extends BaseNumberValidation {
+
+ Impl(final String pointer, final UnaryOperator valueProvider, final double multipleOf) {
+ super("MultipleOf", pointer, valueProvider, multipleOf);
+ }
+
+ @Override
+ protected boolean isValid(final double val) {
+ final double divided = val / bound;
+ return divided == (long) divided;
+ }
+
+ @Override
+ protected Stream toError(final double val) {
+ return Stream.of(new ValidationResult.ValidationError(pointer, val + " is not a multiple of " + bound));
+ }
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/PatternValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/PatternValidation.java
new file mode 100644
index 0000000000000..538d77e2dd01a
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/PatternValidation.java
@@ -0,0 +1,77 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
+
+public class PatternValidation implements ValidationExtension {
+
+ private final Function> predicateFactory;
+
+ public PatternValidation(final Function> predicateFactory) {
+ this.predicateFactory = predicateFactory;
+ }
+
+ @Override
+ public Optional>>
+ create(final ValidationContext model) {
+ if (model.getSchema().getString("type", "object").equals("string")) {
+ return Optional.ofNullable(model.getSchema().get("pattern"))
+ .filter(val -> val.getValueType() == JsonValue.ValueType.STRING)
+ .map(pattern -> new Impl(model.toPointer(), model.getValueProvider(),
+ predicateFactory.apply(JsonString.class.cast(pattern).getString())));
+ }
+ return Optional.empty();
+ }
+
+ private static class Impl extends BaseValidation {
+
+ private final Predicate matcher;
+
+ private Impl(final String pointer, final UnaryOperator valueProvider,
+ final Predicate matcher) {
+ super(pointer, valueProvider, JsonValue.ValueType.STRING);
+ this.matcher = matcher;
+ }
+
+ @Override
+ public Stream onString(final JsonString value) {
+ if (!matcher.test(value.getString())) {
+ return Stream.of(new ValidationResult.ValidationError(pointer, value + " doesn't match " + matcher));
+ }
+ return Stream.empty();
+ }
+
+ @Override
+ public String toString() {
+ return "Pattern{" +
+ "regex=" + matcher +
+ ", pointer='" + pointer + '\'' +
+ '}';
+ }
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/RequiredValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/RequiredValidation.java
new file mode 100644
index 0000000000000..0cc64a55a1109
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/RequiredValidation.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.toSet;
+
+import java.util.Collection;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonObject;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
+
+public class RequiredValidation implements ValidationExtension {
+
+ @Override
+ public Optional>>
+ create(final ValidationContext model) {
+ return ofNullable(model.getSchema().get("required"))
+ .filter(it -> it.getValueType() == JsonValue.ValueType.ARRAY)
+ .map(JsonValue::asJsonArray)
+ .filter(arr -> arr.stream().allMatch(it -> it.getValueType() == JsonValue.ValueType.STRING))
+ .map(arr -> arr.stream().map(it -> JsonString.class.cast(it).getString()).collect(toSet()))
+ .map(required -> new Impl(required, model.getValueProvider(), model.toPointer()));
+ }
+
+ private static class Impl extends BaseValidation {
+
+ private final Collection required;
+
+ private Impl(final Collection required, final UnaryOperator extractor,
+ final String pointer) {
+ super(pointer, extractor, JsonValue.ValueType.OBJECT);
+ this.required = required;
+ }
+
+ @Override
+ public Stream onObject(final JsonObject obj) {
+ if (obj == null || obj == JsonValue.NULL) {
+ return toErrors(required.stream());
+ }
+ return toErrors(required.stream().filter(name -> isNull(obj.get(name))));
+ }
+
+ private Stream toErrors(final Stream fields) {
+ return fields.map(
+ name -> new ValidationResult.ValidationError(pointer, name + " is required and is not present"));
+ }
+
+ @Override
+ public String toString() {
+ return "Required{" +
+ "required=" + required +
+ ", pointer='" + pointer + '\'' +
+ '}';
+ }
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/TypeValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/TypeValidation.java
new file mode 100644
index 0000000000000..93b6c11d114f0
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/TypeValidation.java
@@ -0,0 +1,106 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import static java.util.Comparator.comparing;
+
+import java.util.Collection;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonArray;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
+
+public class TypeValidation implements ValidationExtension {
+
+ @Override
+ public Optional>>
+ create(final ValidationContext model) {
+ final JsonValue value = model.getSchema().get("type");
+ if (value instanceof JsonString) {
+ return Optional.of(new Impl(model.toPointer(), model.getValueProvider(),
+ mapType(JsonString.class.cast(value)).toArray(JsonValue.ValueType[]::new)));
+ }
+ if (value instanceof JsonArray) {
+ return Optional.of(new Impl(model.toPointer(), model.getValueProvider(),
+ value.asJsonArray().stream().flatMap(this::mapType).toArray(JsonValue.ValueType[]::new)));
+ }
+ throw new IllegalArgumentException(value + " is neither an array or string nor a string");
+ }
+
+ private Stream extends JsonValue.ValueType> mapType(final JsonValue value) {
+ switch (JsonString.class.cast(value).getString()) {
+ case "null":
+ return Stream.of(JsonValue.ValueType.NULL);
+ case "string":
+ return Stream.of(JsonValue.ValueType.STRING);
+ case "number", "integer":
+ return Stream.of(JsonValue.ValueType.NUMBER);
+ case "array":
+ return Stream.of(JsonValue.ValueType.ARRAY);
+ case "boolean":
+ return Stream.of(JsonValue.ValueType.FALSE, JsonValue.ValueType.TRUE);
+ case "object":
+ default:
+ return Stream.of(JsonValue.ValueType.OBJECT);
+ }
+ }
+
+ private static class Impl extends BaseValidation {
+
+ private final Collection types;
+
+ private Impl(final String pointer, final UnaryOperator extractor,
+ final JsonValue.ValueType... types) {
+ super(pointer, extractor, types[0] /* ignored anyway */);
+ // note: should we always add NULL? if not it leads to a very weird behavior for partial objects and
+ // required fixes it
+ this.types = Stream.concat(Stream.of(types), Stream.of(JsonValue.ValueType.NULL))
+ .distinct()
+ .sorted(comparing(JsonValue.ValueType::name))
+ .toList();
+ }
+
+ @Override
+ public Stream apply(final JsonValue root) {
+ if (isNull(root)) {
+ return Stream.empty();
+ }
+ final JsonValue value = extractor.apply(root);
+ if (value == null || types.contains(value.getValueType())) {
+ return Stream.empty();
+ }
+ return Stream.of(new ValidationResult.ValidationError(
+ pointer,
+ "Expected " + types + " but got " + value.getValueType()));
+ }
+
+ @Override
+ public String toString() {
+ return "Type{" +
+ "type=" + types +
+ ", pointer='" + pointer + '\'' +
+ '}';
+ }
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/UniqueItemsValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/UniqueItemsValidation.java
new file mode 100644
index 0000000000000..b8b80737a27eb
--- /dev/null
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/jsonschema/spi/builtin/UniqueItemsValidation.java
@@ -0,0 +1,68 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+import java.util.stream.Stream;
+
+import jakarta.json.JsonArray;
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
+
+public class UniqueItemsValidation implements ValidationExtension {
+
+ @Override
+ public Optional>>
+ create(final ValidationContext model) {
+ return Optional.ofNullable(model.getSchema().get("uniqueItems"))
+ .filter(it -> it.getValueType() == JsonValue.ValueType.TRUE)
+ .map(max -> new Impl(model.toPointer(), model.getValueProvider()));
+ }
+
+ private static class Impl extends BaseValidation {
+
+ private Impl(final String pointer,
+ final UnaryOperator extractor) {
+ super(pointer, extractor, JsonValue.ValueType.ARRAY);
+ }
+
+ @Override
+ protected Stream onArray(final JsonArray array) {
+ final Collection uniques = new HashSet<>(array);
+ if (array.size() != uniques.size()) {
+ final Collection duplicated = new ArrayList<>(array);
+ duplicated.removeAll(uniques);
+ return Stream.of(new ValidationResult.ValidationError(pointer, "duplicated items: " + duplicated));
+ }
+ return Stream.empty();
+ }
+
+ @Override
+ public String toString() {
+ return "UniqueItems{" +
+ "pointer='" + pointer + '\'' +
+ '}';
+ }
+ }
+}
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/BaseNumberValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/BaseNumberValidation.java
index 572854eaa4039..3b053088ba2c0 100644
--- a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/BaseNumberValidation.java
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/BaseNumberValidation.java
@@ -18,10 +18,10 @@
import java.util.function.Function;
import java.util.stream.Stream;
-import javax.json.JsonNumber;
-import javax.json.JsonValue;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonValue;
-import org.apache.johnzon.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
/**
* Delete this class when next johnzon-jsonschema release is out
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/BaseValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/BaseValidation.java
index 3d5f7010af7d3..4470e3e5c6ddc 100644
--- a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/BaseValidation.java
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/BaseValidation.java
@@ -18,14 +18,14 @@
import java.util.function.Function;
import java.util.stream.Stream;
-import javax.json.JsonArray;
-import javax.json.JsonNumber;
-import javax.json.JsonObject;
-import javax.json.JsonString;
-import javax.json.JsonValue;
-
-import org.apache.johnzon.jsonschema.ValidationResult;
-import org.apache.johnzon.jsonschema.ValidationResult.ValidationError;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
+
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult.ValidationError;
abstract class BaseValidation implements Function> {
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/EnumValidationWithDefaultValue.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/EnumValidationWithDefaultValue.java
index 19af7364b9f1a..be1eac1c8c17e 100644
--- a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/EnumValidationWithDefaultValue.java
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/EnumValidationWithDefaultValue.java
@@ -22,12 +22,12 @@
import java.util.function.Function;
import java.util.stream.Stream;
-import javax.json.JsonValue;
+import jakarta.json.JsonValue;
-import org.apache.johnzon.jsonschema.ValidationResult;
-import org.apache.johnzon.jsonschema.ValidationResult.ValidationError;
-import org.apache.johnzon.jsonschema.spi.ValidationContext;
-import org.apache.johnzon.jsonschema.spi.builtin.EnumValidation;
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult.ValidationError;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.builtin.EnumValidation;
public class EnumValidationWithDefaultValue extends EnumValidation {
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/MaximumValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/MaximumValidation.java
index 4fbaa507d5236..26b016581085e 100644
--- a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/MaximumValidation.java
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/MaximumValidation.java
@@ -19,13 +19,13 @@
import java.util.function.Function;
import java.util.stream.Stream;
-import javax.json.JsonNumber;
-import javax.json.JsonValue;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonValue;
-import org.apache.johnzon.jsonschema.ValidationResult;
-import org.apache.johnzon.jsonschema.ValidationResult.ValidationError;
-import org.apache.johnzon.jsonschema.spi.ValidationContext;
-import org.apache.johnzon.jsonschema.spi.ValidationExtension;
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult.ValidationError;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
public class MaximumValidation implements ValidationExtension {
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/MinimumValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/MinimumValidation.java
index 2ef744ffd2bfa..2e24d7860cd65 100644
--- a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/MinimumValidation.java
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/MinimumValidation.java
@@ -19,13 +19,13 @@
import java.util.function.Function;
import java.util.stream.Stream;
-import javax.json.JsonNumber;
-import javax.json.JsonValue;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonValue;
-import org.apache.johnzon.jsonschema.ValidationResult;
-import org.apache.johnzon.jsonschema.ValidationResult.ValidationError;
-import org.apache.johnzon.jsonschema.spi.ValidationContext;
-import org.apache.johnzon.jsonschema.spi.ValidationExtension;
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult.ValidationError;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
public class MinimumValidation implements ValidationExtension {
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/RequiredValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/RequiredValidation.java
index 7a14086c2e4e4..96b3dc2717800 100644
--- a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/RequiredValidation.java
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/RequiredValidation.java
@@ -23,13 +23,13 @@
import java.util.function.Function;
import java.util.stream.Stream;
-import javax.json.JsonObject;
-import javax.json.JsonString;
-import javax.json.JsonValue;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
-import org.apache.johnzon.jsonschema.ValidationResult.ValidationError;
-import org.apache.johnzon.jsonschema.spi.ValidationContext;
-import org.apache.johnzon.jsonschema.spi.ValidationExtension;
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult.ValidationError;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
public class RequiredValidation implements ValidationExtension {
diff --git a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/TypeValidation.java b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/TypeValidation.java
index 9b469231397a6..76e111e70f813 100644
--- a/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/TypeValidation.java
+++ b/component-form/component-form-core/src/main/java/org/talend/sdk/component/form/internal/validation/spi/ext/TypeValidation.java
@@ -22,15 +22,15 @@
import java.util.function.Function;
import java.util.stream.Stream;
-import javax.json.JsonArray;
-import javax.json.JsonString;
-import javax.json.JsonValue;
-import javax.json.JsonValue.ValueType;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
+import jakarta.json.JsonValue.ValueType;
-import org.apache.johnzon.jsonschema.ValidationResult;
-import org.apache.johnzon.jsonschema.ValidationResult.ValidationError;
-import org.apache.johnzon.jsonschema.spi.ValidationContext;
-import org.apache.johnzon.jsonschema.spi.ValidationExtension;
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult.ValidationError;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationContext;
+import org.talend.sdk.component.form.internal.validation.jsonschema.spi.ValidationExtension;
public class TypeValidation implements ValidationExtension {
diff --git a/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/api/UiSpecServiceTest.java b/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/api/UiSpecServiceTest.java
index f131174cd1bc8..a1a13be26763d 100644
--- a/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/api/UiSpecServiceTest.java
+++ b/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/api/UiSpecServiceTest.java
@@ -49,10 +49,10 @@
import java.util.function.Consumer;
import java.util.stream.Stream;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
-import javax.json.bind.JsonbConfig;
-import javax.json.bind.config.PropertyOrderStrategy;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.bind.JsonbConfig;
+import jakarta.json.bind.config.PropertyOrderStrategy;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
diff --git a/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/converter/impl/JsonSchemaConverterTest.java b/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/converter/impl/JsonSchemaConverterTest.java
index 2b5b9f171cc68..60170a6f2c6b6 100644
--- a/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/converter/impl/JsonSchemaConverterTest.java
+++ b/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/converter/impl/JsonSchemaConverterTest.java
@@ -33,8 +33,8 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
import org.junit.jupiter.api.Test;
import org.talend.sdk.component.form.api.Client;
diff --git a/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/converter/impl/PropertiesConverterTest.java b/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/converter/impl/PropertiesConverterTest.java
index 765173d0a053a..b9191ff86cb51 100644
--- a/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/converter/impl/PropertiesConverterTest.java
+++ b/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/converter/impl/PropertiesConverterTest.java
@@ -24,8 +24,8 @@
import java.util.LinkedHashMap;
import java.util.Map;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
import org.junit.jupiter.api.Test;
import org.talend.sdk.component.form.internal.converter.PropertyContext;
diff --git a/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/converter/impl/UiSchemaConverterTest.java b/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/converter/impl/UiSchemaConverterTest.java
index 8c3843b8a387a..80bccf7180b81 100644
--- a/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/converter/impl/UiSchemaConverterTest.java
+++ b/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/converter/impl/UiSchemaConverterTest.java
@@ -33,8 +33,8 @@
import java.util.concurrent.CompletionStage;
import java.util.concurrent.atomic.AtomicInteger;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
import org.junit.jupiter.api.Test;
import org.talend.sdk.component.form.internal.converter.CustomPropertyConverter;
diff --git a/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/converter/impl/widget/AbstractWidgetConverterTest.java b/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/converter/impl/widget/AbstractWidgetConverterTest.java
index e9e04428d242e..19a1a0ba285af 100644
--- a/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/converter/impl/widget/AbstractWidgetConverterTest.java
+++ b/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/converter/impl/widget/AbstractWidgetConverterTest.java
@@ -31,9 +31,9 @@
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Stream;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
-import javax.json.bind.JsonbConfig;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.bind.JsonbConfig;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
diff --git a/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/validation/JsonSchemaValidatorFactoryExtRulesTest.java b/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/validation/JsonSchemaValidatorFactoryExtRulesTest.java
new file mode 100644
index 0000000000000..5c73d0eb196a7
--- /dev/null
+++ b/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/validation/JsonSchemaValidatorFactoryExtRulesTest.java
@@ -0,0 +1,113 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.StringReader;
+import java.util.stream.Stream;
+
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonValue;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.talend.sdk.component.form.internal.validation.jsonschema.JsonSchemaValidator;
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
+
+class JsonSchemaValidatorFactoryExtRulesTest {
+
+ private static JsonObject object(final String json) {
+ try (final var reader = Json.createReader(new StringReader(json))) {
+ return reader.readObject();
+ }
+ }
+
+ private static String field(final String fieldSchema) {
+ return "{\"type\":\"object\",\"properties\":{\"a\":" + fieldSchema + "}}";
+ }
+
+ private static Arguments of(final String name, final String schema, final String value, final int errors) {
+ return Arguments.of(name, schema, value, errors);
+ }
+
+ static Stream cases() {
+ return Stream
+ .of(of("enum valid", field("{\"type\":\"string\",\"enum\":[\"x\",\"y\"]}"), "{\"a\":\"x\"}", 0),
+ of("enum other value is tolerated", field("{\"type\":\"string\",\"enum\":[\"x\",\"y\"]}"), "{\"a\":\"z\"}", 0),
+ of("enum null value", field("{\"type\":\"string\",\"enum\":[\"x\",\"y\"]}"), "{\"a\":null}", 1),
+ of("enum missing value", field("{\"type\":\"string\",\"enum\":[\"x\",\"y\"]}"), "{}", 1),
+ of("enum default is valid", field("{\"type\":\"string\",\"enum\":[\"x\"],\"default\":\"x\"}"), "{}", 0),
+ of("enum not an array", field("{\"type\":\"string\",\"enum\":\"x\"}"), "{}", 0),
+ of("type string ok", field("{\"type\":\"string\"}"), "{\"a\":\"s\"}", 0),
+ of("type string ko", field("{\"type\":\"string\"}"), "{\"a\":1}", 1),
+ of("type number", field("{\"type\":\"number\"}"), "{\"a\":1}", 0),
+ of("type boolean", field("{\"type\":\"boolean\"}"), "{\"a\":true}", 0),
+ of("type array", field("{\"type\":\"array\"}"), "{\"a\":[]}", 0),
+ of("type null", field("{\"type\":\"null\"}"), "{\"a\":null}", 0),
+ of("type union ok", field("{\"type\":[\"string\",\"number\"]}"), "{\"a\":1}", 0),
+ of("type union ko", field("{\"type\":[\"string\",\"number\"]}"), "{\"a\":true}", 1),
+ of("type object ko", field("{\"type\":\"object\"}"), "{\"a\":\"s\"}", 1),
+ of("required valued", "{\"type\":\"object\",\"required\":[\"a\"]}", "{\"a\":1}", 0),
+ of("required unvalued", "{\"type\":\"object\",\"required\":[\"a\"]}", "{\"a\":null}", 1),
+ of("required hidden", "{\"type\":\"object\",\"required\":[\"a\"]}", "{}", 0),
+ of("required not strings", "{\"type\":\"object\",\"required\":[1]}", "{}", 0),
+ of("minimum ko", field("{\"type\":\"number\",\"minimum\":5}"), "{\"a\":1}", 1),
+ of("minimum ok", field("{\"type\":\"number\",\"minimum\":5}"), "{\"a\":6}", 0),
+ of("maximum ko", field("{\"type\":\"number\",\"maximum\":5}"), "{\"a\":10}", 1),
+ of("maximum ok", field("{\"type\":\"number\",\"maximum\":5}"), "{\"a\":3}", 0),
+ of("pattern ko", field("{\"type\":\"string\",\"pattern\":\"^a.*\"}"), "{\"a\":\"b\"}", 1),
+ of("pattern ok", field("{\"type\":\"string\",\"pattern\":\"^a.*\"}"), "{\"a\":\"ab\"}", 0),
+ of("pattern not valid in javascript", field("{\"type\":\"string\",\"pattern\":\"(?<=a)b\\\\p{Alpha}\"}"),
+ "{\"a\":\"b\"}", 1));
+ }
+
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("cases")
+ void validate(final String name, final String schema, final String value, final int expectedErrors) {
+ try (final JsonSchemaValidatorFactoryExt factory = new JsonSchemaValidatorFactoryExt();
+ final JsonSchemaValidator validator = factory.newInstance(object(schema))) {
+ final ValidationResult result = validator.apply(object(value));
+ assertEquals(expectedErrors, result.getErrors().size(), () -> name + ": " + result);
+ }
+ }
+
+ @Test
+ void nullRootIsAlwaysValid() {
+ try (final JsonSchemaValidatorFactoryExt factory = new JsonSchemaValidatorFactoryExt();
+ final JsonSchemaValidator validator = factory
+ .newInstance(object(field("{\"type\":\"string\",\"enum\":[\"x\"],\"minimum\":1}")))) {
+ assertTrue(validator.apply(JsonValue.NULL).isSuccess());
+ }
+ }
+
+ @Test
+ void validatorsAreDescribed() {
+ try (final JsonSchemaValidatorFactoryExt factory = new JsonSchemaValidatorFactoryExt()) {
+ final String description = factory
+ .newInstance(object("{\"type\":\"object\",\"required\":[\"a\"],\"properties\":{\"a\":"
+ + "{\"enum\":[\"x\"],\"type\":\"string\"}}}"))
+ .toString();
+ assertTrue(description.contains("Required{"), description);
+ assertTrue(description.contains("Enum{"), description);
+ assertTrue(description.contains("Type{"), description);
+ }
+ }
+}
diff --git a/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/validation/JsonSchemaValidatorFactoryExtTest.java b/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/validation/JsonSchemaValidatorFactoryExtTest.java
index 493dd47628006..1c6bcfaeea5e9 100644
--- a/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/validation/JsonSchemaValidatorFactoryExtTest.java
+++ b/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/validation/JsonSchemaValidatorFactoryExtTest.java
@@ -21,18 +21,18 @@
import java.io.InputStream;
import java.util.List;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonObject;
-import javax.json.JsonValue;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
-import javax.json.spi.JsonProvider;
-
-import org.apache.johnzon.jsonschema.JsonSchemaValidator;
-import org.apache.johnzon.jsonschema.ValidationResult;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonValue;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.spi.JsonProvider;
+
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.talend.sdk.component.form.api.UiSpecService;
+import org.talend.sdk.component.form.internal.validation.jsonschema.JsonSchemaValidator;
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult;
import org.talend.sdk.component.form.internal.validation.spi.ext.EnumValidationWithDefaultValue;
import org.talend.sdk.component.form.internal.validation.spi.ext.MaximumValidation;
import org.talend.sdk.component.form.internal.validation.spi.ext.MinimumValidation;
diff --git a/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/validation/ValidationServiceTest.java b/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/validation/ValidationServiceTest.java
index 0103a23d423ad..81ea4f8402bc1 100644
--- a/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/validation/ValidationServiceTest.java
+++ b/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/validation/ValidationServiceTest.java
@@ -24,19 +24,19 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
-import javax.json.Json;
-import javax.json.JsonObject;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
-import org.apache.johnzon.jsonschema.JsonSchemaValidator;
-import org.apache.johnzon.jsonschema.ValidationResult.ValidationError;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.talend.sdk.component.form.internal.converter.PropertyContext;
import org.talend.sdk.component.form.internal.converter.PropertyContext.Configuration;
import org.talend.sdk.component.form.internal.converter.impl.JsonSchemaConverter;
import org.talend.sdk.component.form.internal.lang.CompletionStages;
+import org.talend.sdk.component.form.internal.validation.jsonschema.JsonSchemaValidator;
+import org.talend.sdk.component.form.internal.validation.jsonschema.ValidationResult.ValidationError;
import org.talend.sdk.component.form.model.jsonschema.JsonSchema;
import org.talend.sdk.component.server.front.model.ConfigTypeNode;
import org.talend.sdk.component.server.front.model.ConfigTypeNodes;
diff --git a/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/validation/jsonschema/JsonSchemaValidatorFactoryTest.java b/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/validation/jsonschema/JsonSchemaValidatorFactoryTest.java
new file mode 100644
index 0000000000000..19db4ff74db7d
--- /dev/null
+++ b/component-form/component-form-core/src/test/java/org/talend/sdk/component/form/internal/validation/jsonschema/JsonSchemaValidatorFactoryTest.java
@@ -0,0 +1,201 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.form.internal.validation.jsonschema;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.StringReader;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonValue;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+class JsonSchemaValidatorFactoryTest {
+
+ private static JsonObject object(final String json) {
+ try (final var reader = Json.createReader(new StringReader(json))) {
+ return reader.readObject();
+ }
+ }
+
+ // each keyword is validated on the "a" property of the root object
+ private static String field(final String fieldSchema) {
+ return "{\"type\":\"object\",\"properties\":{\"a\":" + fieldSchema + "}}";
+ }
+
+ private static Arguments of(final String name, final String schema, final String value, final int errors) {
+ return Arguments.of(name, schema, value, errors);
+ }
+
+ static Stream cases() {
+ return Stream
+ .of(of("required missing", "{\"type\":\"object\",\"required\":[\"a\"]}", "{}", 1),
+ of("required present", "{\"type\":\"object\",\"required\":[\"a\"]}", "{\"a\":1}", 0),
+ of("minProperties ko", "{\"type\":\"object\",\"minProperties\":1}", "{}", 1),
+ of("minProperties ok", "{\"type\":\"object\",\"minProperties\":1}", "{\"a\":1}", 0),
+ of("maxProperties ko", "{\"type\":\"object\",\"maxProperties\":1}", "{\"a\":1,\"b\":2}", 1),
+ of("maxProperties ok", "{\"type\":\"object\",\"maxProperties\":1}", "{\"a\":1}", 0),
+ of("type string ko", field("{\"type\":\"string\"}"), "{\"a\":1}", 1),
+ of("type string ok", field("{\"type\":\"string\"}"), "{\"a\":\"x\"}", 0),
+ of("type number ko", field("{\"type\":\"number\"}"), "{\"a\":\"x\"}", 1),
+ of("type boolean ko", field("{\"type\":\"boolean\"}"), "{\"a\":\"x\"}", 1),
+ of("type boolean ok", field("{\"type\":\"boolean\"}"), "{\"a\":true}", 0),
+ of("type array ko", field("{\"type\":\"array\"}"), "{\"a\":1}", 1),
+ of("type array ok", field("{\"type\":\"array\"}"), "{\"a\":[]}", 0),
+ of("type object ko", field("{\"type\":\"object\"}"), "{\"a\":1}", 1),
+ of("type object ok", field("{\"type\":\"object\"}"), "{\"a\":{}}", 0),
+ of("type null ko", field("{\"type\":\"null\"}"), "{\"a\":1}", 1),
+ of("type union ko", field("{\"type\":[\"string\",\"null\"]}"), "{\"a\":1}", 1),
+ of("type union ok", field("{\"type\":[\"string\",\"null\"]}"), "{\"a\":\"x\"}", 0),
+ of("type union null", field("{\"type\":[\"string\",\"null\"]}"), "{\"a\":null}", 0),
+ of("integer ko", field("{\"type\":\"integer\"}"), "{\"a\":1.5}", 1),
+ of("integer ok", field("{\"type\":\"integer\"}"), "{\"a\":2}", 0),
+ of("enum ko", field("{\"type\":\"string\",\"enum\":[\"x\",\"y\"]}"), "{\"a\":\"z\"}", 1),
+ of("enum ok", field("{\"type\":\"string\",\"enum\":[\"x\",\"y\"]}"), "{\"a\":\"x\"}", 0),
+ of("enum nullable", field("{\"type\":\"string\",\"enum\":[\"x\"],\"nullable\":true}"),
+ "{\"a\":null}", 0),
+ of("multipleOf ko", field("{\"type\":\"number\",\"multipleOf\":3}"), "{\"a\":4}", 1),
+ of("multipleOf ok", field("{\"type\":\"number\",\"multipleOf\":3}"), "{\"a\":6}", 0),
+ of("maximum ko", field("{\"type\":\"number\",\"maximum\":5}"), "{\"a\":6}", 1),
+ of("maximum ok", field("{\"type\":\"number\",\"maximum\":5}"), "{\"a\":5}", 0),
+ of("minimum ko", field("{\"type\":\"number\",\"minimum\":5}"), "{\"a\":4}", 1),
+ of("minimum ok", field("{\"type\":\"number\",\"minimum\":5}"), "{\"a\":5}", 0),
+ of("exclusiveMaximum ko", field("{\"type\":\"number\",\"exclusiveMaximum\":5}"), "{\"a\":5}",
+ 1),
+ of("exclusiveMaximum ok", field("{\"type\":\"number\",\"exclusiveMaximum\":5}"), "{\"a\":4}",
+ 0),
+ of("exclusiveMinimum ko", field("{\"type\":\"number\",\"exclusiveMinimum\":5}"), "{\"a\":5}",
+ 1),
+ of("exclusiveMinimum ok", field("{\"type\":\"number\",\"exclusiveMinimum\":5}"), "{\"a\":6}",
+ 0),
+ of("maxLength ko", field("{\"type\":\"string\",\"maxLength\":2}"), "{\"a\":\"abc\"}", 1),
+ of("maxLength ok", field("{\"type\":\"string\",\"maxLength\":2}"), "{\"a\":\"ab\"}", 0),
+ of("minLength ko", field("{\"type\":\"string\",\"minLength\":2}"), "{\"a\":\"a\"}", 1),
+ of("minLength ok", field("{\"type\":\"string\",\"minLength\":2}"), "{\"a\":\"ab\"}", 0),
+ of("pattern ko", field("{\"type\":\"string\",\"pattern\":\"^a+$\"}"), "{\"a\":\"b\"}", 1),
+ of("pattern ok", field("{\"type\":\"string\",\"pattern\":\"^a+$\"}"), "{\"a\":\"aa\"}", 0),
+ of("maxItems ko", field("{\"type\":\"array\",\"maxItems\":1}"), "{\"a\":[1,2]}", 1),
+ of("maxItems ok", field("{\"type\":\"array\",\"maxItems\":1}"), "{\"a\":[1]}", 0),
+ of("minItems ko", field("{\"type\":\"array\",\"minItems\":2}"), "{\"a\":[1]}", 1),
+ of("minItems ok", field("{\"type\":\"array\",\"minItems\":2}"), "{\"a\":[1,2]}", 0),
+ of("uniqueItems ko", field("{\"type\":\"array\",\"uniqueItems\":true}"), "{\"a\":[1,1]}", 1),
+ of("uniqueItems ok", field("{\"type\":\"array\",\"uniqueItems\":true}"), "{\"a\":[1,2]}", 0),
+ of("contains ko", field("{\"type\":\"array\",\"contains\":{\"type\":\"string\"}}"),
+ "{\"a\":[1,2]}", 1),
+ of("contains ok", field("{\"type\":\"array\",\"contains\":{\"type\":\"string\"}}"),
+ "{\"a\":[1,\"x\"]}", 0),
+ of("items schema ko",
+ field("{\"type\":\"array\",\"items\":{\"type\":\"number\",\"minimum\":1}}"),
+ "{\"a\":[1,0]}", 1),
+ of("items schema ok",
+ field("{\"type\":\"array\",\"items\":{\"type\":\"number\",\"minimum\":1}}"),
+ "{\"a\":[1,2]}", 0),
+ of("items array of schemas ko",
+ field("{\"type\":\"array\",\"items\":[{\"type\":\"object\",\"required\":[\"k\"]}]}"),
+ "{\"a\":[{\"k\":1},{}]}", 1),
+ of("items unsupported schema kind", field("{\"type\":\"array\",\"items\":true}"),
+ "{\"a\":[1]}", 0),
+ of("patternProperties ko",
+ "{\"type\":\"object\",\"patternProperties\":{\"^x.*\":{\"type\":\"number\"}}}",
+ "{\"xa\":\"s\",\"b\":\"s\"}", 1),
+ of("patternProperties ok",
+ "{\"type\":\"object\",\"patternProperties\":{\"^x.*\":{\"type\":\"number\"}}}",
+ "{\"xa\":1}", 0),
+ of("nested properties",
+ field("{\"type\":\"object\",\"properties\":{\"b\":{\"type\":\"string\"}}}"),
+ "{\"a\":{\"b\":1}}", 1),
+ of("missing optional nested value",
+ field("{\"type\":\"object\",\"properties\":{\"b\":{\"type\":\"string\"}}}"), "{}", 0));
+ }
+
+ @ParameterizedTest(name = "{0}")
+ @MethodSource("cases")
+ void validate(final String name, final String schema, final String value, final int expectedErrors) {
+ try (final JsonSchemaValidatorFactory factory = new JsonSchemaValidatorFactory();
+ final JsonSchemaValidator validator = factory.newInstance(object(schema))) {
+ final ValidationResult result = validator.apply(object(value));
+ assertEquals(expectedErrors, result.getErrors().size(), () -> name + ": " + result);
+ assertEquals(expectedErrors == 0, result.isSuccess());
+ }
+ }
+
+ @Test
+ void errorMessage() {
+ try (final JsonSchemaValidatorFactory factory = new JsonSchemaValidatorFactory();
+ final JsonSchemaValidator validator = factory.newInstance(object(field("{\"type\":\"string\"}")))) {
+ final ValidationResult result = validator.apply(object("{\"a\":1}"));
+ final ValidationResult.ValidationError error = result.getErrors().iterator().next();
+ assertTrue(error.getMessage().startsWith("Expected"), error.getMessage());
+ }
+ }
+
+ @Test
+ void resultAccessors() {
+ final ValidationResult result = new ValidationResult();
+ assertTrue(result.isSuccess());
+ final ValidationResult.ValidationError error = new ValidationResult.ValidationError();
+ error.setField("/f");
+ error.setMessage("m");
+ result.setErrors(List.of(error));
+ assertFalse(result.isSuccess());
+ assertEquals("/f", error.getField());
+ assertEquals("m", error.getMessage());
+ assertTrue(result.toString().contains("/f"));
+ assertTrue(error.toString().contains("m"));
+ }
+
+ @Test
+ void invalidTypeIsRejected() {
+ final JsonObject schema = object("{\"type\":1}");
+ try (final JsonSchemaValidatorFactory factory = new JsonSchemaValidatorFactory()) {
+ assertThrows(RuntimeException.class, () -> factory.newInstance(schema));
+ }
+ }
+
+ @Test
+ void extensionsAndRegexFactoryCanBeCustomized() {
+ try (final JsonSchemaValidatorFactory factory = new JsonSchemaValidatorFactory()) {
+ factory.setExtensions().appendExtensions(model -> Optional.of(value -> Stream.empty()));
+ factory.setRegexFactory(regex -> input -> true);
+ final JsonSchemaValidator validator = factory.newInstance(object("{\"type\":\"string\"}"));
+ assertTrue(validator.apply(JsonValue.NULL).isSuccess());
+ assertTrue(validator.toString().startsWith("JsonSchemaValidator{"));
+ assertTrue(factory.createDefaultValidations().size() > 10);
+ }
+ }
+
+ @Test
+ void validatorsAreDescribed() {
+ try (final JsonSchemaValidatorFactory factory = new JsonSchemaValidatorFactory()) {
+ final String description = factory
+ .newInstance(object(field("{\"type\":\"number\",\"minimum\":1,\"maximum\":2}")))
+ .toString();
+ assertTrue(description.contains("Minimum{bound=1.0"), description);
+ assertTrue(description.contains("Maximum{bound=2.0"), description);
+ }
+ }
+}
diff --git a/component-form/component-form-model/pom.xml b/component-form/component-form-model/pom.xml
index 3637235cb7a52..056640ac39cac 100644
--- a/component-form/component-form-model/pom.xml
+++ b/component-form/component-form-model/pom.xml
@@ -31,21 +31,22 @@
${talend.build.name.base}.form.model
+
- org.apache.geronimo.specs
- geronimo-jsonb_1.0_spec
- ${geronimo-jsonb.version}
+ jakarta.json
+ jakarta.json-api
- org.apache.geronimo.specs
- geronimo-json_1.1_spec
- ${geronimo-json.version}
+ jakarta.json.bind
+ jakarta.json.bind-api
org.apache.johnzon
johnzon-jsonb
+ ${johnzon.version}
test
diff --git a/component-form/component-form-model/src/main/java/org/talend/sdk/component/form/model/jsonschema/JsonSchema.java b/component-form/component-form-model/src/main/java/org/talend/sdk/component/form/model/jsonschema/JsonSchema.java
index 1d620622ba6cc..914d56b28f7fc 100644
--- a/component-form/component-form-model/src/main/java/org/talend/sdk/component/form/model/jsonschema/JsonSchema.java
+++ b/component-form/component-form-model/src/main/java/org/talend/sdk/component/form/model/jsonschema/JsonSchema.java
@@ -21,7 +21,7 @@
import java.util.LinkedHashMap;
import java.util.Map;
-import javax.json.bind.annotation.JsonbProperty;
+import jakarta.json.bind.annotation.JsonbProperty;
import lombok.Data;
diff --git a/component-form/component-form-model/src/main/java/org/talend/sdk/component/form/model/uischema/UiSchema.java b/component-form/component-form-model/src/main/java/org/talend/sdk/component/form/model/uischema/UiSchema.java
index e6a88ff4fdcb7..b7074b4ddbf5f 100644
--- a/component-form/component-form-model/src/main/java/org/talend/sdk/component/form/model/uischema/UiSchema.java
+++ b/component-form/component-form-model/src/main/java/org/talend/sdk/component/form/model/uischema/UiSchema.java
@@ -26,7 +26,7 @@
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
-import javax.json.bind.annotation.JsonbTransient;
+import jakarta.json.bind.annotation.JsonbTransient;
import lombok.AllArgsConstructor;
import lombok.Data;
diff --git a/component-form/component-form-model/src/test/java/org/talend/sdk/component/form/model/UiTest.java b/component-form/component-form-model/src/test/java/org/talend/sdk/component/form/model/UiTest.java
index fefa58517782d..47947ab5ffb8a 100644
--- a/component-form/component-form-model/src/test/java/org/talend/sdk/component/form/model/UiTest.java
+++ b/component-form/component-form-model/src/test/java/org/talend/sdk/component/form/model/UiTest.java
@@ -15,16 +15,16 @@
*/
package org.talend.sdk.component.form.model;
-import static javax.json.bind.config.PropertyOrderStrategy.LEXICOGRAPHICAL;
+import static jakarta.json.bind.config.PropertyOrderStrategy.LEXICOGRAPHICAL;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import static org.talend.sdk.component.form.model.Ui.ui;
import static org.talend.sdk.component.form.model.jsonschema.JsonSchema.jsonSchema;
import static org.talend.sdk.component.form.model.uischema.UiSchema.uiSchema;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
-import javax.json.bind.JsonbConfig;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.bind.JsonbConfig;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
diff --git a/component-form/component-uispec-mapper/pom.xml b/component-form/component-uispec-mapper/pom.xml
index 97d73e751a597..4e9d893f2e23a 100644
--- a/component-form/component-uispec-mapper/pom.xml
+++ b/component-form/component-uispec-mapper/pom.xml
@@ -36,15 +36,15 @@
org.slf4j
slf4j-api
+
- org.apache.geronimo.specs
- geronimo-json_1.1_spec
- ${geronimo-json.version}
+ jakarta.json
+ jakarta.json-api
- org.apache.geronimo.specs
- geronimo-jsonb_1.0_spec
- ${geronimo-jsonb.version}
+ jakarta.json.bind
+ jakarta.json.bind-api
org.talend.sdk.component
@@ -55,6 +55,7 @@
org.apache.johnzon
johnzon-jsonb
+ ${johnzon.version}
test
diff --git a/component-form/component-uispec-mapper/src/test/java/org/talend/sdk/component/form/uispec/mapper/impl/UiSpecMapperImplTest.java b/component-form/component-uispec-mapper/src/test/java/org/talend/sdk/component/form/uispec/mapper/impl/UiSpecMapperImplTest.java
index 7fc9fc5b7bdd1..1b6d5bfe2704a 100644
--- a/component-form/component-uispec-mapper/src/test/java/org/talend/sdk/component/form/uispec/mapper/impl/UiSpecMapperImplTest.java
+++ b/component-form/component-uispec-mapper/src/test/java/org/talend/sdk/component/form/uispec/mapper/impl/UiSpecMapperImplTest.java
@@ -28,10 +28,10 @@
import java.util.function.Supplier;
import java.util.stream.IntStream;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
-import javax.json.bind.JsonbConfig;
-import javax.json.bind.config.PropertyOrderStrategy;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.bind.JsonbConfig;
+import jakarta.json.bind.config.PropertyOrderStrategy;
import org.junit.jupiter.api.Test;
import org.talend.sdk.component.form.model.Ui;
diff --git a/component-runtime-beam/pom.xml b/component-runtime-beam/pom.xml
index ce46be7870fa8..c4de26560f847 100644
--- a/component-runtime-beam/pom.xml
+++ b/component-runtime-beam/pom.xml
@@ -42,6 +42,16 @@
+
+
+ jakarta.json
+ jakarta.json-api
+
+
+ jakarta.json.bind
+ jakarta.json.bind-api
+
org.talend.sdk.component
component-runtime-manager
diff --git a/component-runtime-beam/src/it/serialization-over-cluster/src/main/java/org/talend/sdk/component/beam/it/clusterserialization/Main.java b/component-runtime-beam/src/it/serialization-over-cluster/src/main/java/org/talend/sdk/component/beam/it/clusterserialization/Main.java
index aa04f62fd43bc..12b3c398e4d8f 100644
--- a/component-runtime-beam/src/it/serialization-over-cluster/src/main/java/org/talend/sdk/component/beam/it/clusterserialization/Main.java
+++ b/component-runtime-beam/src/it/serialization-over-cluster/src/main/java/org/talend/sdk/component/beam/it/clusterserialization/Main.java
@@ -21,10 +21,10 @@
import java.io.IOException;
import java.util.HashMap;
-import javax.json.Json;
-import javax.json.JsonObject;
-import javax.json.bind.JsonbBuilder;
-import javax.json.spi.JsonProvider;
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.spi.JsonProvider;
import org.apache.beam.sdk.Pipeline;
import org.apache.beam.sdk.PipelineResult;
diff --git a/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/BaseProcessorFn.java b/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/BaseProcessorFn.java
index da51d6accf366..ea23a7aaa2959 100644
--- a/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/BaseProcessorFn.java
+++ b/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/BaseProcessorFn.java
@@ -26,7 +26,7 @@
import java.util.Map;
import java.util.function.Consumer;
-import javax.json.bind.Jsonb;
+import jakarta.json.bind.Jsonb;
import org.apache.beam.sdk.transforms.DoFn;
import org.talend.sdk.component.api.processor.OutputEmitter;
diff --git a/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/TalendIO.java b/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/TalendIO.java
index 94d8f256c0ac3..b9f4026e37908 100644
--- a/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/TalendIO.java
+++ b/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/TalendIO.java
@@ -26,7 +26,7 @@
import java.util.function.Consumer;
import java.util.stream.Stream;
-import javax.json.bind.Jsonb;
+import jakarta.json.bind.Jsonb;
import org.apache.beam.sdk.annotations.Experimental;
import org.apache.beam.sdk.coders.Coder;
diff --git a/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/coder/JsonbCoder.java b/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/coder/JsonbCoder.java
index bc4d945e0a0da..e2b450f9fb8a6 100644
--- a/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/coder/JsonbCoder.java
+++ b/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/coder/JsonbCoder.java
@@ -26,7 +26,7 @@
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
-import javax.json.bind.Jsonb;
+import jakarta.json.bind.Jsonb;
import org.apache.beam.sdk.coders.CustomCoder;
import org.apache.beam.sdk.util.VarInt;
diff --git a/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/coder/JsonpJsonObjectCoder.java b/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/coder/JsonpJsonObjectCoder.java
index 2168a8e805186..7be7b86ac762a 100644
--- a/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/coder/JsonpJsonObjectCoder.java
+++ b/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/coder/JsonpJsonObjectCoder.java
@@ -24,11 +24,11 @@
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
-import javax.json.JsonObject;
-import javax.json.JsonReader;
-import javax.json.JsonReaderFactory;
-import javax.json.JsonWriter;
-import javax.json.JsonWriterFactory;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonReader;
+import jakarta.json.JsonReaderFactory;
+import jakarta.json.JsonWriter;
+import jakarta.json.JsonWriterFactory;
import org.apache.beam.sdk.coders.CustomCoder;
import org.apache.beam.sdk.util.VarInt;
diff --git a/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/spi/record/AvroRecord.java b/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/spi/record/AvroRecord.java
index cf1630bf84dad..957c34893142f 100644
--- a/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/spi/record/AvroRecord.java
+++ b/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/spi/record/AvroRecord.java
@@ -32,7 +32,7 @@
import java.util.List;
import java.util.Objects;
-import javax.json.bind.annotation.JsonbTransient;
+import jakarta.json.bind.annotation.JsonbTransient;
import org.apache.avro.LogicalTypes;
import org.apache.avro.generic.GenericArray;
diff --git a/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/spi/record/AvroSchema.java b/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/spi/record/AvroSchema.java
index 930b5c654a6f9..b2b16b3693ca4 100644
--- a/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/spi/record/AvroSchema.java
+++ b/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/spi/record/AvroSchema.java
@@ -30,7 +30,7 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import javax.json.bind.annotation.JsonbTransient;
+import jakarta.json.bind.annotation.JsonbTransient;
import org.apache.avro.LogicalType;
import org.apache.avro.LogicalTypes;
diff --git a/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/transform/avro/IndexedRecordToJson.java b/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/transform/avro/IndexedRecordToJson.java
index 2c3183d2b69a8..642499870fb28 100644
--- a/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/transform/avro/IndexedRecordToJson.java
+++ b/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/transform/avro/IndexedRecordToJson.java
@@ -17,9 +17,9 @@
import java.io.StringReader;
-import javax.json.JsonObject;
-import javax.json.JsonReader;
-import javax.json.JsonReaderFactory;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonReader;
+import jakarta.json.JsonReaderFactory;
import org.apache.avro.generic.IndexedRecord;
import org.apache.beam.sdk.coders.Coder;
diff --git a/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/transform/avro/JsonIndexedRecord.java b/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/transform/avro/JsonIndexedRecord.java
index 83e6161541067..e490445e5109a 100644
--- a/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/transform/avro/JsonIndexedRecord.java
+++ b/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/transform/avro/JsonIndexedRecord.java
@@ -17,10 +17,10 @@
import static java.util.stream.Collectors.toList;
-import javax.json.JsonNumber;
-import javax.json.JsonObject;
-import javax.json.JsonString;
-import javax.json.JsonValue;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericData;
diff --git a/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/transform/avro/JsonToIndexedRecord.java b/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/transform/avro/JsonToIndexedRecord.java
index e5a9e5ba02c62..56738faa9ddd0 100644
--- a/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/transform/avro/JsonToIndexedRecord.java
+++ b/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/transform/avro/JsonToIndexedRecord.java
@@ -15,7 +15,7 @@
*/
package org.talend.sdk.component.runtime.beam.transform.avro;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.apache.avro.Schema;
import org.apache.avro.generic.IndexedRecord;
diff --git a/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/transform/avro/SchemalessJsonToIndexedRecord.java b/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/transform/avro/SchemalessJsonToIndexedRecord.java
index 2dc5115db96c3..7a70cb7a95c74 100644
--- a/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/transform/avro/SchemalessJsonToIndexedRecord.java
+++ b/component-runtime-beam/src/main/java/org/talend/sdk/component/runtime/beam/transform/avro/SchemalessJsonToIndexedRecord.java
@@ -17,10 +17,10 @@
import static java.util.Arrays.asList;
-import javax.json.JsonArray;
-import javax.json.JsonNumber;
-import javax.json.JsonObject;
-import javax.json.JsonValue;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonValue;
import org.apache.avro.Schema;
import org.apache.avro.generic.IndexedRecord;
diff --git a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/NativeWrappedIOTest.java b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/NativeWrappedIOTest.java
index aafde29fbb618..1a3c6b501f910 100644
--- a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/NativeWrappedIOTest.java
+++ b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/NativeWrappedIOTest.java
@@ -34,11 +34,11 @@
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Stream;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonObject;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbConfig;
-import javax.json.spi.JsonProvider;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbConfig;
+import jakarta.json.spi.JsonProvider;
import org.apache.beam.sdk.io.jdbc.JdbcIO;
import org.apache.beam.sdk.testing.PAssert;
diff --git a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/TalendIOTest.java b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/TalendIOTest.java
index 14e195d111e30..78b61da8c9ea0 100644
--- a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/TalendIOTest.java
+++ b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/TalendIOTest.java
@@ -41,8 +41,8 @@
import java.util.stream.IntStream;
import java.util.stream.StreamSupport;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
import org.apache.beam.sdk.PipelineResult;
import org.apache.beam.sdk.testing.PAssert;
diff --git a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/coder/JsonRoundTripTest.java b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/coder/JsonRoundTripTest.java
index bb689d6325765..9504c8d2f27a8 100644
--- a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/coder/JsonRoundTripTest.java
+++ b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/coder/JsonRoundTripTest.java
@@ -22,7 +22,7 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import javax.json.Json;
+import jakarta.json.Json;
import org.junit.jupiter.api.Test;
diff --git a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/coder/JsonpJsonObjectCoderTest.java b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/coder/JsonpJsonObjectCoderTest.java
index 7bb2977af55ab..a7044ba93a7be 100644
--- a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/coder/JsonpJsonObjectCoderTest.java
+++ b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/coder/JsonpJsonObjectCoderTest.java
@@ -29,8 +29,8 @@
import java.util.stream.StreamSupport;
import java.util.zip.GZIPInputStream;
-import javax.json.Json;
-import javax.json.JsonObject;
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
import org.apache.beam.sdk.coders.IterableCoder;
import org.apache.beam.sdk.util.VarInt;
diff --git a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/coder/registry/SchemaRegistryCoderTest.java b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/coder/registry/SchemaRegistryCoderTest.java
index 65eea8d400aee..3338a692e30c1 100644
--- a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/coder/registry/SchemaRegistryCoderTest.java
+++ b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/coder/registry/SchemaRegistryCoderTest.java
@@ -24,10 +24,10 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import javax.json.Json;
-import javax.json.JsonBuilderFactory;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
+import jakarta.json.Json;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
import org.junit.jupiter.api.Test;
import org.talend.sdk.component.api.record.Record;
diff --git a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/factory/service/AutoValueFluentApiFactoryTest.java b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/factory/service/AutoValueFluentApiFactoryTest.java
index b06d603bacf21..0e25354fbc067 100644
--- a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/factory/service/AutoValueFluentApiFactoryTest.java
+++ b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/factory/service/AutoValueFluentApiFactoryTest.java
@@ -22,7 +22,7 @@
import java.lang.reflect.Field;
import java.util.HashMap;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.apache.beam.sdk.options.ValueProvider;
import org.junit.jupiter.api.Test;
diff --git a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/factory/service/io/AutoValue_CustomJdbcIO_DataSourceConfiguration.java b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/factory/service/io/AutoValue_CustomJdbcIO_DataSourceConfiguration.java
index b42f2576a5e00..1facc37481089 100644
--- a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/factory/service/io/AutoValue_CustomJdbcIO_DataSourceConfiguration.java
+++ b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/factory/service/io/AutoValue_CustomJdbcIO_DataSourceConfiguration.java
@@ -15,9 +15,10 @@
*/
package org.talend.sdk.component.runtime.beam.factory.service.io;
-import javax.annotation.Generated;
import javax.sql.DataSource;
+import jakarta.annotation.Generated;
+
@Generated("from_com.google.auto.value.processor.AutoValueProcessor")
final class AutoValue_CustomJdbcIO_DataSourceConfiguration extends CustomJdbcIO.DataSourceConfiguration {
diff --git a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/factory/service/io/AutoValue_CustomJdbcIO_Read.java b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/factory/service/io/AutoValue_CustomJdbcIO_Read.java
index 095207ea19070..328eb44058332 100644
--- a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/factory/service/io/AutoValue_CustomJdbcIO_Read.java
+++ b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/factory/service/io/AutoValue_CustomJdbcIO_Read.java
@@ -15,7 +15,7 @@
*/
package org.talend.sdk.component.runtime.beam.factory.service.io;
-import javax.annotation.Generated;
+import jakarta.annotation.Generated;
import org.apache.beam.sdk.options.ValueProvider;
diff --git a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/spi/record/AvroRecordBuilderTest.java b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/spi/record/AvroRecordBuilderTest.java
index 68d46345b1a1d..df4dfb223b53a 100644
--- a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/spi/record/AvroRecordBuilderTest.java
+++ b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/spi/record/AvroRecordBuilderTest.java
@@ -37,9 +37,9 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
-import javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonObject;
+import jakarta.json.Json;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonObject;
import org.apache.avro.Schema.Field;
import org.apache.avro.generic.GenericDatumWriter;
diff --git a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/spi/record/AvroRecordConvertersTest.java b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/spi/record/AvroRecordConvertersTest.java
index d3d50d33588eb..ac00fe616c546 100644
--- a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/spi/record/AvroRecordConvertersTest.java
+++ b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/spi/record/AvroRecordConvertersTest.java
@@ -27,11 +27,11 @@
import java.util.Collection;
import java.util.List;
-import javax.json.Json;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonReaderFactory;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
+import jakarta.json.Json;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonReaderFactory;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
diff --git a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/spi/record/AvroRecordTest.java b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/spi/record/AvroRecordTest.java
index 4b70a8a387336..794dcd1f4c5ed 100644
--- a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/spi/record/AvroRecordTest.java
+++ b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/spi/record/AvroRecordTest.java
@@ -55,9 +55,9 @@
import java.util.TimeZone;
import java.util.function.Supplier;
-import javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonObject;
+import jakarta.json.Json;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonObject;
import org.apache.avro.LogicalType;
import org.apache.avro.LogicalTypes;
diff --git a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/spi/record/JsonSchemaSerializationTest.java b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/spi/record/JsonSchemaSerializationTest.java
index 36092d21addc0..48d0c2f624d9e 100644
--- a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/spi/record/JsonSchemaSerializationTest.java
+++ b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/spi/record/JsonSchemaSerializationTest.java
@@ -20,10 +20,10 @@
import static org.talend.sdk.component.api.record.Schema.Type.RECORD;
import static org.talend.sdk.component.api.record.Schema.Type.STRING;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
-import javax.json.bind.JsonbConfig;
-import javax.json.bind.config.PropertyOrderStrategy;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.bind.JsonbConfig;
+import jakarta.json.bind.config.PropertyOrderStrategy;
import org.junit.jupiter.api.Test;
import org.talend.sdk.component.api.record.Schema;
diff --git a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/transform/avro/JsonToIndexedRecordTest.java b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/transform/avro/JsonToIndexedRecordTest.java
index c3dcd22e5a270..c138d8d7e4a26 100644
--- a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/transform/avro/JsonToIndexedRecordTest.java
+++ b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/transform/avro/JsonToIndexedRecordTest.java
@@ -20,7 +20,7 @@
import java.util.List;
import java.util.stream.StreamSupport;
-import javax.json.JsonBuilderFactory;
+import jakarta.json.JsonBuilderFactory;
import org.apache.avro.Schema;
import org.apache.avro.SchemaBuilder;
diff --git a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/transform/avro/SchemalessJsonToIndexedRecordTest.java b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/transform/avro/SchemalessJsonToIndexedRecordTest.java
index 51b38ffbd0f23..e1ead2cce541c 100644
--- a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/transform/avro/SchemalessJsonToIndexedRecordTest.java
+++ b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/transform/avro/SchemalessJsonToIndexedRecordTest.java
@@ -21,7 +21,7 @@
import java.util.List;
import java.util.stream.StreamSupport;
-import javax.json.JsonBuilderFactory;
+import jakarta.json.JsonBuilderFactory;
import org.apache.avro.Schema;
import org.apache.avro.SchemaBuilder;
diff --git a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/transformer/BeamIOTransformerTest.java b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/transformer/BeamIOTransformerTest.java
index a2fa679f9fdbb..da73a6211b0e9 100644
--- a/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/transformer/BeamIOTransformerTest.java
+++ b/component-runtime-beam/src/test/java/org/talend/sdk/component/runtime/beam/transformer/BeamIOTransformerTest.java
@@ -36,10 +36,10 @@
import java.util.function.Predicate;
import java.util.function.Supplier;
-import javax.json.Json;
-import javax.json.JsonObject;
-import javax.json.JsonReaderFactory;
-import javax.json.JsonWriterFactory;
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonReaderFactory;
+import jakarta.json.JsonWriterFactory;
import org.apache.beam.sdk.Pipeline;
import org.apache.beam.sdk.coders.Coder;
@@ -187,9 +187,16 @@ private void scenario(final Scenario runnable) {
final Predicate parentPredicate = it -> SetValidator.class.getName().equals(it)
|| !(it.startsWith(prefix) || it.startsWith(JdbcSource.class.getName()))
|| Pojo.class.getName().equals(it);
+ // QTDI-3497 (experimental, jakarta-only spike): without this, jakarta.json.spi.JsonProvider's
+ // ServiceLoader lookup (triggered here under the plugin TCCL by BeamIOTransformer's advice, see
+ // JdbcSource.WorkAroundCoder.encode -> JsonpJsonObjectCoder.of) can't see johnzon's
+ // META-INF/services registration and falls back to jakarta.json-api's hardcoded default
+ // provider (org.eclipse.parsson.JsonProviderImpl), which isn't on the classpath. Mirrors
+ // ComponentManager#KNOWN_PARENT_RESOURCES.
+ final Predicate resourcesFilter = name -> name.contains("META-INF/services/jakarta.json");
try (final ConfigurableClassLoader loader = new ConfigurableClassLoader("test",
new URL[] { jarLocation(BeamIOTransformerTest.class).toURI().toURL() }, originalLoader,
- parentPredicate, parentPredicate.negate(), new String[0], new String[0])) {
+ parentPredicate, parentPredicate.negate(), new String[0], new String[0], resourcesFilter)) {
// thread.setContextClassLoader(loader); // don't set it, this is what we test!
final BeamIOTransformer transformer = new BeamIOTransformer();
loader.registerTransformer(transformer);
diff --git a/component-runtime-beam/src/test/java/org/talend/test/ConcatProcessor.java b/component-runtime-beam/src/test/java/org/talend/test/ConcatProcessor.java
index 77aa9154e4c71..3de3441ed1b10 100644
--- a/component-runtime-beam/src/test/java/org/talend/test/ConcatProcessor.java
+++ b/component-runtime-beam/src/test/java/org/talend/test/ConcatProcessor.java
@@ -17,8 +17,8 @@
import java.io.Serializable;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonObject;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.processor.ElementListener;
import org.talend.sdk.component.api.processor.Input;
diff --git a/component-runtime-beam/src/test/java/org/talend/test/FileOutput.java b/component-runtime-beam/src/test/java/org/talend/test/FileOutput.java
index c9e26b24a841a..cdacfa1f37c0d 100644
--- a/component-runtime-beam/src/test/java/org/talend/test/FileOutput.java
+++ b/component-runtime-beam/src/test/java/org/talend/test/FileOutput.java
@@ -20,8 +20,8 @@
import java.io.Serializable;
import java.io.Writer;
-import javax.annotation.PreDestroy;
-import javax.json.JsonObject;
+import jakarta.annotation.PreDestroy;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.processor.ElementListener;
import org.talend.sdk.component.api.processor.Processor;
diff --git a/component-runtime-beam/src/test/java/org/talend/test/FormatterProcessor.java b/component-runtime-beam/src/test/java/org/talend/test/FormatterProcessor.java
index 6f6e1d6c92bf8..644f78ad71450 100644
--- a/component-runtime-beam/src/test/java/org/talend/test/FormatterProcessor.java
+++ b/component-runtime-beam/src/test/java/org/talend/test/FormatterProcessor.java
@@ -19,8 +19,8 @@
import java.io.Serializable;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonObject;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.processor.ElementListener;
import org.talend.sdk.component.api.processor.Input;
diff --git a/component-runtime-beam/src/test/java/org/talend/test/ListInput.java b/component-runtime-beam/src/test/java/org/talend/test/ListInput.java
index 8a773727435ce..cde56ca32c6c1 100644
--- a/component-runtime-beam/src/test/java/org/talend/test/ListInput.java
+++ b/component-runtime-beam/src/test/java/org/talend/test/ListInput.java
@@ -20,8 +20,8 @@
import java.util.Iterator;
import java.util.List;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonObject;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.input.Emitter;
diff --git a/component-runtime-beam/src/test/java/org/talend/test/RejectOutput.java b/component-runtime-beam/src/test/java/org/talend/test/RejectOutput.java
index b9b8346a1c219..283f27a76b667 100644
--- a/component-runtime-beam/src/test/java/org/talend/test/RejectOutput.java
+++ b/component-runtime-beam/src/test/java/org/talend/test/RejectOutput.java
@@ -21,8 +21,8 @@
import java.io.Serializable;
import java.io.Writer;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.processor.ElementListener;
diff --git a/component-runtime-beam/src/test/java/org/talend/test/wrapped/ASource.java b/component-runtime-beam/src/test/java/org/talend/test/wrapped/ASource.java
index 18b34fbc17803..fad00fa399525 100644
--- a/component-runtime-beam/src/test/java/org/talend/test/wrapped/ASource.java
+++ b/component-runtime-beam/src/test/java/org/talend/test/wrapped/ASource.java
@@ -22,8 +22,8 @@
import java.util.List;
import java.util.NoSuchElementException;
-import javax.json.Json;
-import javax.json.JsonObject;
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
import org.apache.beam.sdk.coders.Coder;
import org.apache.beam.sdk.io.BoundedSource;
diff --git a/component-runtime-beam/src/test/java/org/talend/test/wrapped/JdbcSource.java b/component-runtime-beam/src/test/java/org/talend/test/wrapped/JdbcSource.java
index c056ada2eabfb..e1931b8f845cc 100644
--- a/component-runtime-beam/src/test/java/org/talend/test/wrapped/JdbcSource.java
+++ b/component-runtime-beam/src/test/java/org/talend/test/wrapped/JdbcSource.java
@@ -28,9 +28,9 @@
import java.util.stream.IntStream;
import java.util.stream.Stream;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonObjectBuilder;
import org.apache.beam.sdk.annotations.Experimental;
import org.apache.beam.sdk.coders.Coder;
diff --git a/component-runtime-design-extension/src/test/java/org/talend/test/Input.java b/component-runtime-design-extension/src/test/java/org/talend/test/Input.java
index 61e1ea4955566..3e156d501dcd7 100644
--- a/component-runtime-design-extension/src/test/java/org/talend/test/Input.java
+++ b/component-runtime-design-extension/src/test/java/org/talend/test/Input.java
@@ -17,7 +17,7 @@
import java.io.Serializable;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.input.Producer;
diff --git a/component-runtime-design-extension/src/test/java/org/talend/test/multipletrees/TheComponent1.java b/component-runtime-design-extension/src/test/java/org/talend/test/multipletrees/TheComponent1.java
index a2b12180af846..be57b30102f3d 100644
--- a/component-runtime-design-extension/src/test/java/org/talend/test/multipletrees/TheComponent1.java
+++ b/component-runtime-design-extension/src/test/java/org/talend/test/multipletrees/TheComponent1.java
@@ -20,7 +20,7 @@
import java.io.Serializable;
import java.util.List;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.component.Icon;
import org.talend.sdk.component.api.configuration.Option;
diff --git a/component-runtime-design-extension/src/test/java/org/talend/test/multipletrees/TheComponent2.java b/component-runtime-design-extension/src/test/java/org/talend/test/multipletrees/TheComponent2.java
index 47b45f5e4bc11..0a3e36df350a4 100644
--- a/component-runtime-design-extension/src/test/java/org/talend/test/multipletrees/TheComponent2.java
+++ b/component-runtime-design-extension/src/test/java/org/talend/test/multipletrees/TheComponent2.java
@@ -20,7 +20,7 @@
import java.io.Serializable;
import java.util.List;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.component.Icon;
import org.talend.sdk.component.api.configuration.Option;
diff --git a/component-runtime-design-extension/src/test/java/org/talend/test/multipletrees/TheComponent3.java b/component-runtime-design-extension/src/test/java/org/talend/test/multipletrees/TheComponent3.java
index d5a92ec993209..22fcb7eec257c 100644
--- a/component-runtime-design-extension/src/test/java/org/talend/test/multipletrees/TheComponent3.java
+++ b/component-runtime-design-extension/src/test/java/org/talend/test/multipletrees/TheComponent3.java
@@ -20,7 +20,7 @@
import java.io.Serializable;
import java.util.List;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.component.Icon;
import org.talend.sdk.component.api.configuration.Option;
diff --git a/component-runtime-design-extension/src/test/java/org/talend/test/multipletrees/TheComponent4.java b/component-runtime-design-extension/src/test/java/org/talend/test/multipletrees/TheComponent4.java
index cb77e495f8123..2a2ddccc52602 100644
--- a/component-runtime-design-extension/src/test/java/org/talend/test/multipletrees/TheComponent4.java
+++ b/component-runtime-design-extension/src/test/java/org/talend/test/multipletrees/TheComponent4.java
@@ -20,7 +20,7 @@
import java.io.Serializable;
import java.util.List;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.component.Icon;
import org.talend.sdk.component.api.configuration.Option;
diff --git a/component-runtime-impl/pom.xml b/component-runtime-impl/pom.xml
index e5f975f289c89..394cba3a6903e 100644
--- a/component-runtime-impl/pom.xml
+++ b/component-runtime-impl/pom.xml
@@ -33,6 +33,9 @@
${talend.build.name.base}.impl
+
org.talend.sdk.component
@@ -46,6 +49,7 @@
org.apache.johnzon
johnzon-jsonb
+ ${johnzon.version}
org.apache.logging.log4j
diff --git a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/base/LifecycleImpl.java b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/base/LifecycleImpl.java
index 9fb3742eb0188..3948e04cc1db1 100644
--- a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/base/LifecycleImpl.java
+++ b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/base/LifecycleImpl.java
@@ -23,8 +23,8 @@
import java.util.Objects;
import java.util.stream.Stream;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import org.talend.sdk.component.runtime.serialization.ContainerFinder;
diff --git a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/input/CheckpointState.java b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/input/CheckpointState.java
index 2ff232d69216c..7a32ea304f130 100644
--- a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/input/CheckpointState.java
+++ b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/input/CheckpointState.java
@@ -15,11 +15,11 @@
*/
package org.talend.sdk.component.runtime.input;
-import javax.json.Json;
-import javax.json.JsonObject;
-import javax.json.bind.Jsonb;
-import javax.json.bind.annotation.JsonbProperty;
-import javax.json.bind.spi.JsonbProvider;
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.annotation.JsonbProperty;
+import jakarta.json.bind.spi.JsonbProvider;
import lombok.AllArgsConstructor;
import lombok.Data;
diff --git a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/input/InputImpl.java b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/input/InputImpl.java
index 9c31312e5ca83..477ab8ed86be3 100644
--- a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/input/InputImpl.java
+++ b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/input/InputImpl.java
@@ -26,7 +26,7 @@
import java.lang.reflect.Method;
import java.util.function.Consumer;
-import javax.json.bind.Jsonb;
+import jakarta.json.bind.Jsonb;
import org.talend.sdk.component.api.component.Version;
import org.talend.sdk.component.api.input.Producer;
diff --git a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/input/StreamingInputImpl.java b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/input/StreamingInputImpl.java
index 2e7cece96f93d..cea7b1f19fea2 100644
--- a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/input/StreamingInputImpl.java
+++ b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/input/StreamingInputImpl.java
@@ -33,7 +33,7 @@
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
-import javax.annotation.PostConstruct;
+import jakarta.annotation.PostConstruct;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.runtime.input.Streaming.RetryConfiguration;
diff --git a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/output/ProcessorImpl.java b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/output/ProcessorImpl.java
index 14bbe406f96d4..f9248552acd9b 100644
--- a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/output/ProcessorImpl.java
+++ b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/output/ProcessorImpl.java
@@ -42,13 +42,13 @@
import java.util.function.Function;
import java.util.stream.Stream;
-import javax.json.Json;
-import javax.json.JsonBuilderFactory;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
-import javax.json.bind.JsonbConfig;
-import javax.json.bind.config.BinaryDataStrategy;
-import javax.json.spi.JsonProvider;
+import jakarta.json.Json;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.bind.JsonbConfig;
+import jakarta.json.bind.config.BinaryDataStrategy;
+import jakarta.json.spi.JsonProvider;
import org.talend.sdk.component.api.processor.AfterGroup;
import org.talend.sdk.component.api.processor.BeforeGroup;
diff --git a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/RecordConverters.java b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/RecordConverters.java
index 69d036fb1b352..80ed7470c388d 100644
--- a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/RecordConverters.java
+++ b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/RecordConverters.java
@@ -40,16 +40,16 @@
import java.util.stream.Collector;
import java.util.stream.Stream;
-import javax.json.JsonArray;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonNumber;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
-import javax.json.JsonString;
-import javax.json.JsonValue;
-import javax.json.bind.Jsonb;
-import javax.json.spi.JsonProvider;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonArrayBuilder;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonObjectBuilder;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.spi.JsonProvider;
import org.apache.johnzon.core.JsonLongImpl;
import org.apache.johnzon.jsonb.extension.JsonValueReader;
diff --git a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/RecordImpl.java b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/RecordImpl.java
index a8efe15a3a1ee..472c66af2fcc6 100644
--- a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/RecordImpl.java
+++ b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/RecordImpl.java
@@ -47,14 +47,14 @@
import java.util.function.Function;
import java.util.stream.Collectors;
-import javax.json.Json;
-import javax.json.JsonObject;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
-import javax.json.bind.JsonbConfig;
-import javax.json.bind.annotation.JsonbTransient;
-import javax.json.bind.config.PropertyOrderStrategy;
-import javax.json.spi.JsonProvider;
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.bind.JsonbConfig;
+import jakarta.json.bind.annotation.JsonbTransient;
+import jakarta.json.bind.config.PropertyOrderStrategy;
+import jakarta.json.spi.JsonProvider;
import org.talend.sdk.component.api.record.OrderedMap;
import org.talend.sdk.component.api.record.Record;
diff --git a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/SchemaImpl.java b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/SchemaImpl.java
index 8695e4f734220..0c486dba143f1 100644
--- a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/SchemaImpl.java
+++ b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/SchemaImpl.java
@@ -29,7 +29,7 @@
import java.util.Objects;
import java.util.stream.Stream;
-import javax.json.bind.annotation.JsonbTransient;
+import jakarta.json.bind.annotation.JsonbTransient;
import org.talend.sdk.component.api.record.OrderedMap;
import org.talend.sdk.component.api.record.Schema;
diff --git a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/Schemas.java b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/Schemas.java
index d27bf4de6bb51..64252ce5c2d40 100644
--- a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/Schemas.java
+++ b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/Schemas.java
@@ -23,7 +23,7 @@
import java.util.Map;
import java.util.stream.Stream;
-import javax.json.bind.annotation.JsonbTransient;
+import jakarta.json.bind.annotation.JsonbTransient;
import org.talend.sdk.component.api.record.Schema;
diff --git a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/json/PojoJsonbProvider.java b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/json/PojoJsonbProvider.java
index a6b84d1d64b34..66fa0fb6c5479 100644
--- a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/json/PojoJsonbProvider.java
+++ b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/json/PojoJsonbProvider.java
@@ -17,7 +17,7 @@
import java.util.function.Supplier;
-import javax.json.bind.Jsonb;
+import jakarta.json.bind.Jsonb;
@FunctionalInterface
public interface PojoJsonbProvider extends Supplier {
diff --git a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/json/RecordJsonGenerator.java b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/json/RecordJsonGenerator.java
index 8a9c98c67d0e1..a25271a65514f 100644
--- a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/json/RecordJsonGenerator.java
+++ b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/record/json/RecordJsonGenerator.java
@@ -32,15 +32,15 @@
import java.util.function.Supplier;
import java.util.stream.Collector;
-import javax.json.JsonArray;
-import javax.json.JsonNumber;
-import javax.json.JsonObject;
-import javax.json.JsonString;
-import javax.json.JsonValue;
-import javax.json.JsonValue.ValueType;
-import javax.json.bind.Jsonb;
-import javax.json.stream.JsonGenerator;
-import javax.json.stream.JsonGeneratorFactory;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
+import jakarta.json.JsonValue.ValueType;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.stream.JsonGenerator;
+import jakarta.json.stream.JsonGeneratorFactory;
import org.talend.sdk.component.api.record.Record;
import org.talend.sdk.component.api.record.Schema;
diff --git a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/reflect/Parameters.java b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/reflect/Parameters.java
index a5d26d2905918..5b9a6a327a6a0 100644
--- a/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/reflect/Parameters.java
+++ b/component-runtime-impl/src/main/java/org/talend/sdk/component/runtime/reflect/Parameters.java
@@ -22,7 +22,7 @@
import java.lang.reflect.Type;
import java.util.Collection;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.record.Record;
diff --git a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/base/LifecycleImplTest.java b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/base/LifecycleImplTest.java
index 184cdf9f84643..1fd9266a8ba4d 100644
--- a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/base/LifecycleImplTest.java
+++ b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/base/LifecycleImplTest.java
@@ -23,8 +23,8 @@
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import org.junit.jupiter.api.Test;
diff --git a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/input/InputImplTest.java b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/input/InputImplTest.java
index 47a0ad392053b..9ef7adcfc9495 100644
--- a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/input/InputImplTest.java
+++ b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/input/InputImplTest.java
@@ -24,8 +24,8 @@
import java.io.Serializable;
import java.util.stream.IntStream;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import org.junit.jupiter.api.Test;
import org.talend.sdk.component.api.input.Producer;
diff --git a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/input/StreamingInputImplTest.java b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/input/StreamingInputImplTest.java
index a88aaa5792a69..0a7f6eaa5f575 100644
--- a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/input/StreamingInputImplTest.java
+++ b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/input/StreamingInputImplTest.java
@@ -28,7 +28,7 @@
import java.util.List;
import java.util.concurrent.TimeUnit;
-import javax.annotation.PostConstruct;
+import jakarta.annotation.PostConstruct;
import org.junit.jupiter.api.Test;
import org.talend.sdk.component.api.configuration.Option;
diff --git a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/jsonb/MultipleFormatDateAdapterTest.java b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/jsonb/MultipleFormatDateAdapterTest.java
index f711268126823..14f2cb9a597f6 100644
--- a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/jsonb/MultipleFormatDateAdapterTest.java
+++ b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/jsonb/MultipleFormatDateAdapterTest.java
@@ -22,9 +22,9 @@
import java.time.ZonedDateTime;
import java.util.Date;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
-import javax.json.bind.JsonbConfig;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.bind.JsonbConfig;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
diff --git a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/output/ProcessorImplTest.java b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/output/ProcessorImplTest.java
index 7e5f40e418d64..57fb70aacd0bc 100644
--- a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/output/ProcessorImplTest.java
+++ b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/output/ProcessorImplTest.java
@@ -31,8 +31,8 @@
import java.util.Collection;
import java.util.stream.IntStream;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import org.junit.jupiter.api.Test;
import org.talend.sdk.component.api.processor.AfterGroup;
diff --git a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/record/PluralRecordExtension.java b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/record/PluralRecordExtension.java
index 135526c66418f..a9873b42f99cb 100644
--- a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/record/PluralRecordExtension.java
+++ b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/record/PluralRecordExtension.java
@@ -23,12 +23,12 @@
import java.util.Map;
import java.util.function.Supplier;
-import javax.json.Json;
-import javax.json.JsonBuilderFactory;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
-import javax.json.spi.JsonProvider;
-import javax.json.stream.JsonGeneratorFactory;
+import jakarta.json.Json;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.spi.JsonProvider;
+import jakarta.json.stream.JsonGeneratorFactory;
import org.apache.johnzon.core.JsonProviderImpl;
import org.apache.johnzon.mapper.MapperBuilder;
diff --git a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/record/RecordBuilderImplTest.java b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/record/RecordBuilderImplTest.java
index 142769c231547..5e4468f7bf611 100644
--- a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/record/RecordBuilderImplTest.java
+++ b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/record/RecordBuilderImplTest.java
@@ -39,7 +39,7 @@
import java.util.stream.Collectors;
import java.util.stream.IntStream;
-import javax.json.bind.annotation.JsonbTransient;
+import jakarta.json.bind.annotation.JsonbTransient;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
diff --git a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/record/RecordConvertersTest.java b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/record/RecordConvertersTest.java
index bc4ca5ce19bd9..59d846a07ceec 100644
--- a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/record/RecordConvertersTest.java
+++ b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/record/RecordConvertersTest.java
@@ -36,17 +36,17 @@
import java.util.List;
import java.util.stream.Stream;
-import javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonObject;
-import javax.json.JsonValue;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
-import javax.json.bind.JsonbConfig;
-import javax.json.bind.config.BinaryDataStrategy;
-import javax.json.bind.config.PropertyOrderStrategy;
-import javax.json.spi.JsonProvider;
+import jakarta.json.Json;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonValue;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.bind.JsonbConfig;
+import jakarta.json.bind.config.BinaryDataStrategy;
+import jakarta.json.bind.config.PropertyOrderStrategy;
+import jakarta.json.spi.JsonProvider;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
diff --git a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/record/SchemaImplTest.java b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/record/SchemaImplTest.java
index 798b097689533..e470e6818f5b3 100644
--- a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/record/SchemaImplTest.java
+++ b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/record/SchemaImplTest.java
@@ -30,10 +30,10 @@
import java.util.Objects;
import java.util.stream.IntStream;
-import javax.json.Json;
-import javax.json.JsonString;
-import javax.json.JsonValue;
-import javax.json.JsonValue.ValueType;
+import jakarta.json.Json;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
+import jakarta.json.JsonValue.ValueType;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.RepeatedTest;
diff --git a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/record/json/RecordJsonGeneratorTest.java b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/record/json/RecordJsonGeneratorTest.java
index 13491b4888b8c..f5c7478ac5f80 100644
--- a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/record/json/RecordJsonGeneratorTest.java
+++ b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/record/json/RecordJsonGeneratorTest.java
@@ -17,7 +17,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
-import javax.json.bind.Jsonb;
+import jakarta.json.bind.Jsonb;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
diff --git a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/serialization/DynamicContainerFinder.java b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/serialization/DynamicContainerFinder.java
index 748f1a6033c24..8e23cc84f7310 100644
--- a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/serialization/DynamicContainerFinder.java
+++ b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/serialization/DynamicContainerFinder.java
@@ -19,8 +19,8 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
import org.talend.sdk.component.api.service.record.RecordBuilderFactory;
import org.talend.sdk.component.runtime.record.RecordBuilderFactoryImpl;
diff --git a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/standalone/DriverRunnerImplTest.java b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/standalone/DriverRunnerImplTest.java
index d9799e4070984..c61a11bcbd501 100644
--- a/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/standalone/DriverRunnerImplTest.java
+++ b/component-runtime-impl/src/test/java/org/talend/sdk/component/runtime/standalone/DriverRunnerImplTest.java
@@ -20,8 +20,8 @@
import java.io.Serializable;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import org.junit.jupiter.api.Test;
import org.talend.sdk.component.api.standalone.RunAtDriver;
diff --git a/component-runtime-manager/module-knowledge.md b/component-runtime-manager/module-knowledge.md
new file mode 100644
index 0000000000000..3c5121e53cd6b
--- /dev/null
+++ b/component-runtime-manager/module-knowledge.md
@@ -0,0 +1,23 @@
+# Module knowledge — component-runtime-manager
+
+## JSON-B provider resolution
+
+### `createPojoJsonbBuilder`'s Johnzon-specific reflection breaks when another JSON-B provider wins ServiceLoader resolution
+
+[2026-09-22 | QTDI-3358] `DefaultServiceProvider.createPojoJsonbBuilder` calls plain
+`javax.json.bind.JsonbBuilder.newBuilder()` and then reflectively reaches into a private
+Johnzon-only `MapperBuilder builder` field (via `getDeclaredField("builder")`) to force
+`setDoCloseOnStreams(true)`. This silently assumes Johnzon's `JohnzonBuilder` is always the
+`JsonbProvider` that `ServiceLoader` resolves. That assumption breaks whenever another module on
+the same classpath re-pins the JSON-B provider stack — e.g. `component-server`'s
+`dependencyManagement` moving `johnzon-core`/`johnzon-mapper` to the jakarta line while still
+needing a javax-line `javax.json.bind.spi.JsonbProvider` (QTDI-3358's jakarta migration pulled in
+Yasson + `org.glassfish:javax.json` for that leftover javax lookup). Yasson's builder impl has no
+`builder` field, so the reflection throws `NoSuchFieldException`, previously rethrown as a fatal
+`IllegalStateException` and crashing any consumer that reaches this code path with a non-Johnzon
+provider on the classpath. **Fix applied**: guard the reflective block behind
+`jsonbBuilder instanceof org.apache.johnzon.jsonb.JohnzonBuilder` and skip the
+`doCloseOnStreams` optimization (with a debug log) when a different provider is resolved, instead
+of treating it as an error. Any future change to this method — or to a module's JSON-B
+dependency wiring — should re-check which provider actually wins `ServiceLoader` resolution on
+that module's classpath before assuming Johnzon-specific internals are reachable.
diff --git a/component-runtime-manager/pom.xml b/component-runtime-manager/pom.xml
index 92b361ee3fa49..981b46ce04de2 100644
--- a/component-runtime-manager/pom.xml
+++ b/component-runtime-manager/pom.xml
@@ -75,9 +75,12 @@
+
org.apache.johnzon
johnzon-core
+ ${johnzon.version}
diff --git a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/ComponentManager.java b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/ComponentManager.java
index 5325c71c2883a..847e01735e1d1 100644
--- a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/ComponentManager.java
+++ b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/ComponentManager.java
@@ -86,22 +86,22 @@
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.json.JsonArray;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonObject;
-import javax.json.JsonReaderFactory;
-import javax.json.JsonString;
-import javax.json.JsonValue;
-import javax.json.JsonWriterFactory;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbConfig;
-import javax.json.bind.config.BinaryDataStrategy;
-import javax.json.bind.spi.JsonbProvider;
-import javax.json.spi.JsonProvider;
-import javax.json.stream.JsonGeneratorFactory;
-import javax.json.stream.JsonParserFactory;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonReaderFactory;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
+import jakarta.json.JsonWriterFactory;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbConfig;
+import jakarta.json.bind.config.BinaryDataStrategy;
+import jakarta.json.bind.spi.JsonbProvider;
+import jakarta.json.spi.JsonProvider;
+import jakarta.json.stream.JsonGeneratorFactory;
+import jakarta.json.stream.JsonParserFactory;
import org.apache.xbean.asm9.Type;
import org.apache.xbean.finder.AnnotationFinder;
@@ -205,7 +205,20 @@ public class ComponentManager implements AutoCloseable {
public static final String PROPERTY_PARENT_RESOURCES =
"talend.component.manager.classloader.container.parentResources";
- protected static final String[] KNOWN_PARENT_RESOURCES = { "/xmlMappings/" };
+ // QTDI-3497 (experimental, jakarta-only spike): classesFilter already forces "org.apache.johnzon."
+ // and "jakarta.json." classes to always resolve from the parent (manager) classloader, so that a
+ // single Johnzon/JSON-P/JSON-B instance is shared across the manager and every plugin container.
+ // But that class-level delegation alone isn't enough: some Johnzon internals (e.g.
+ // org.apache.johnzon.mapper.MapperBuilder#build) call jakarta.json.spi.JsonProvider.provider() /
+ // jakarta.json.bind.spi.JsonbProvider.provider() themselves as an internal fallback - even when an
+ // explicit JsonProvider was already supplied via JsonbBuilder#withProvider - using whatever
+ // classloader is the current thread's context classloader at that point (e.g. a plugin's isolated
+ // container classloader, see ComponentManager#executeInContainer). Without these resource entries,
+ // that ServiceLoader lookup can't see Johnzon's own META-INF/services/jakarta.json*.spi.*Provider
+ // registration from inside a plugin container, and fails with a JsonException.
+ protected static final String[] KNOWN_PARENT_RESOURCES =
+ { "/xmlMappings/", "META-INF/services/jakarta.json.spi.JsonProvider",
+ "META-INF/services/jakarta.json.bind.spi.JsonbProvider" };
private static class SingletonHolder {
@@ -321,7 +334,7 @@ public String[] categories() {
@Getter
protected final ContainerManager container;
- // tcomp (org.talend + javax.annotation + jsonp) + logging (slf4j) are/can be provided service
+ // tcomp (org.talend + jakarta.annotation + jsonp) + logging (slf4j) are/can be provided service
// + tcomp "runtime" indeed (invisible from the components but required for the runtime
private final Filter classesFilter;
@@ -429,8 +442,8 @@ public ComponentManager(final Path m2, final String dependenciesResource, final
classesFilter = new FilterList(Stream.concat(
Stream.of("org.talend.sdk.component.api.",
"org.talend.sdk.component.spi.",
- "javax.annotation.",
- "javax.json.",
+ "jakarta.annotation.",
+ "jakarta.json.",
"org.talend.sdk.component.classloader.",
"org.talend.sdk.component.runtime.",
"org.talend.sdk.component.container.",
@@ -541,20 +554,20 @@ public Path resolve(final String path) {
recordBuilderFactoryProvider, propertyEditorRegistry);
}
+ // Intentionally *not* referencing org.apache.johnzon.jsonb.JohnzonProvider directly: some downstream
+ // modules (e.g. component-server) pin johnzon-core/johnzon-jsonb to the jakarta.json.* line, whose
+ // classes no longer implement jakarta.json.bind.spi.JsonbProvider. A hardcoded "new JohnzonProvider()"
+ // whose declared return type is the javax interface fails class verification (VerifyError) as soon
+ // as this class is loaded, before the try/catch below ever runs. Going through the ServiceLoader-based
+ // JsonbProvider.provider() keeps this class link-safe regardless of which johnzon-core is on the
+ // classpath; whichever jakarta.json.bind.spi.JsonbProvider implementation is actually present wins.
private JsonbProvider loadJsonbProvider() {
- try {
- return new org.apache.johnzon.jsonb.JohnzonProvider();
- } catch (final RuntimeException re) {
- return JsonbProvider.provider();
- }
+ return JsonbProvider.provider();
}
+ // See loadJsonbProvider() above - same rationale applies to jakarta.json.spi.JsonProvider.
private JsonProvider loadJsonProvider() {
- try {
- return new org.apache.johnzon.core.JsonProviderImpl();
- } catch (final RuntimeException re) {
- return JsonProvider.provider();
- }
+ return JsonProvider.provider();
}
protected Supplier getLocalSupplier() {
diff --git a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/chain/internal/JobImpl.java b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/chain/internal/JobImpl.java
index 93054348251aa..763154b1bc371 100644
--- a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/chain/internal/JobImpl.java
+++ b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/chain/internal/JobImpl.java
@@ -43,9 +43,9 @@
import java.util.function.Function;
import java.util.function.Supplier;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
-import javax.json.bind.JsonbConfig;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.bind.JsonbConfig;
import org.talend.sdk.component.api.processor.OutputEmitter;
import org.talend.sdk.component.api.record.Record;
diff --git a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/json/PreComputedJsonpProvider.java b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/json/PreComputedJsonpProvider.java
index fdfedf3c711c3..b037068c8369c 100644
--- a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/json/PreComputedJsonpProvider.java
+++ b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/json/PreComputedJsonpProvider.java
@@ -26,28 +26,28 @@
import java.util.Collection;
import java.util.Map;
-import javax.json.JsonArray;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonMergePatch;
-import javax.json.JsonNumber;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
-import javax.json.JsonPatch;
-import javax.json.JsonPatchBuilder;
-import javax.json.JsonPointer;
-import javax.json.JsonReader;
-import javax.json.JsonReaderFactory;
-import javax.json.JsonString;
-import javax.json.JsonStructure;
-import javax.json.JsonValue;
-import javax.json.JsonWriter;
-import javax.json.JsonWriterFactory;
-import javax.json.spi.JsonProvider;
-import javax.json.stream.JsonGenerator;
-import javax.json.stream.JsonGeneratorFactory;
-import javax.json.stream.JsonParser;
-import javax.json.stream.JsonParserFactory;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonArrayBuilder;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonMergePatch;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonObjectBuilder;
+import jakarta.json.JsonPatch;
+import jakarta.json.JsonPatchBuilder;
+import jakarta.json.JsonPointer;
+import jakarta.json.JsonReader;
+import jakarta.json.JsonReaderFactory;
+import jakarta.json.JsonString;
+import jakarta.json.JsonStructure;
+import jakarta.json.JsonValue;
+import jakarta.json.JsonWriter;
+import jakarta.json.JsonWriterFactory;
+import jakarta.json.spi.JsonProvider;
+import jakarta.json.stream.JsonGenerator;
+import jakarta.json.stream.JsonGeneratorFactory;
+import jakarta.json.stream.JsonParser;
+import jakarta.json.stream.JsonParserFactory;
import org.talend.sdk.component.runtime.serialization.SerializableService;
@@ -86,8 +86,11 @@ public JsonObjectBuilder createObjectBuilder(final JsonObject jsonObject) {
}
@Override
- public JsonObjectBuilder createObjectBuilder(final Map map) {
- return builderFactory.createObjectBuilder(map);
+ @SuppressWarnings("unchecked")
+ public JsonObjectBuilder createObjectBuilder(final Map map) {
+ // JsonBuilderFactory#createObjectBuilder only accepts Map (jakarta.json-api
+ // 2.1 widened JsonProvider's own signature to Map but not this one)
+ return builderFactory.createObjectBuilder((Map) map);
}
@Override
diff --git a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/reflect/ParameterModelService.java b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/reflect/ParameterModelService.java
index ceb12cc206e5f..0afaae104fc1d 100644
--- a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/reflect/ParameterModelService.java
+++ b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/reflect/ParameterModelService.java
@@ -108,7 +108,9 @@ public boolean isService(final Param parameter) {
|| type.isAnnotationPresent(Internationalized.class)
|| Stream.of(type.getMethods()).anyMatch(m -> m.isAnnotationPresent(Request.class))
|| (type.getName().startsWith("org.talend.sdk.component.") && type.getName().contains(".service."))
- || type.getName().startsWith("javax."));
+ // QTDI-3497 (experimental, jakarta-only spike): javax.* JDK/JSON-P/JSON-B service types are
+ // renamed to jakarta.* in this spike, keep recognizing them as framework-injected services.
+ || type.getName().startsWith("javax.") || type.getName().startsWith("jakarta."));
}
public List buildParameterMetas(final Stream parameters, final Class> declaringClass,
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 d2d3cbd8d9471..efae57a990fc0 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
@@ -56,15 +56,15 @@
import java.util.stream.Collector;
import java.util.stream.Stream;
-import javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonNumber;
-import javax.json.JsonObject;
-import javax.json.JsonReader;
-import javax.json.JsonReaderFactory;
-import javax.json.JsonString;
-import javax.json.JsonValue;
-import javax.json.spi.JsonProvider;
+import jakarta.json.Json;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonReader;
+import jakarta.json.JsonReaderFactory;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
+import jakarta.json.spi.JsonProvider;
import org.apache.xbean.propertyeditor.PropertyEditorRegistry;
import org.apache.xbean.recipe.ObjectRecipe;
diff --git a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/reflect/visibility/PayloadMapper.java b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/reflect/visibility/PayloadMapper.java
index bdd4d8eecaeb5..9f14d7bf54307 100644
--- a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/reflect/visibility/PayloadMapper.java
+++ b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/reflect/visibility/PayloadMapper.java
@@ -15,22 +15,22 @@
*/
package org.talend.sdk.component.runtime.manager.reflect.visibility;
+import static jakarta.json.stream.JsonCollectors.toJsonArray;
import static java.util.Collections.emptyMap;
import static java.util.Comparator.comparing;
import static java.util.Optional.ofNullable;
-import static javax.json.stream.JsonCollectors.toJsonArray;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.stream.Stream;
-import javax.json.JsonArray;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
-import javax.json.JsonValue;
-import javax.json.spi.JsonProvider;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonObjectBuilder;
+import jakarta.json.JsonValue;
+import jakarta.json.spi.JsonProvider;
import org.talend.sdk.component.runtime.manager.ParameterMeta;
diff --git a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/reflect/visibility/VisibilityService.java b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/reflect/visibility/VisibilityService.java
index ee4f02618c2f7..427e23184b6d9 100644
--- a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/reflect/visibility/VisibilityService.java
+++ b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/reflect/visibility/VisibilityService.java
@@ -29,12 +29,12 @@
import java.util.stream.IntStream;
import java.util.stream.Stream;
-import javax.json.JsonNumber;
-import javax.json.JsonObject;
-import javax.json.JsonPointer;
-import javax.json.JsonString;
-import javax.json.JsonValue;
-import javax.json.spi.JsonProvider;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonPointer;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
+import jakarta.json.spi.JsonProvider;
import org.talend.sdk.component.runtime.manager.ParameterMeta;
diff --git a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/DefaultServiceProvider.java b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/DefaultServiceProvider.java
index 04e18a1d72757..f718b848673ec 100644
--- a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/DefaultServiceProvider.java
+++ b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/DefaultServiceProvider.java
@@ -36,17 +36,18 @@
import java.util.function.Supplier;
import java.util.stream.Stream;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonReaderFactory;
-import javax.json.JsonWriterFactory;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
-import javax.json.bind.JsonbConfig;
-import javax.json.bind.spi.JsonbProvider;
-import javax.json.spi.JsonProvider;
-import javax.json.stream.JsonGeneratorFactory;
-import javax.json.stream.JsonParserFactory;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonReaderFactory;
+import jakarta.json.JsonWriterFactory;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.bind.JsonbConfig;
+import jakarta.json.bind.spi.JsonbProvider;
+import jakarta.json.spi.JsonProvider;
+import jakarta.json.stream.JsonGeneratorFactory;
+import jakarta.json.stream.JsonParserFactory;
+import org.apache.johnzon.jsonb.JohnzonBuilder;
import org.apache.johnzon.mapper.MapperBuilder;
import org.talend.sdk.component.api.record.RecordPointerFactory;
import org.talend.sdk.component.api.service.cache.LocalCache;
@@ -221,22 +222,38 @@ private Object doLookup(final String id, final ClassLoader loader,
}
private JsonbBuilder createPojoJsonbBuilder(final String id, final Supplier jsonb) {
+ // QTDI-3497 (experimental, jakarta-only spike): use the already-resolved jsonbProvider instance
+ // instead of the no-arg JsonbBuilder.newBuilder(), which triggers its own ServiceLoader.load()
+ // lookup using the *current* thread context classloader. When this runs inside a plugin's
+ // isolated container classloader (see ComponentManager#executeInContainer), that fresh lookup
+ // is not reliable: the plugin classloader doesn't reliably expose johnzon's
+ // META-INF/services/jakarta.json.bind.spi.JsonbProvider registration to ServiceLoader, causing
+ // a JsonbException. jsonbProvider was already resolved once, safely, in the ComponentManager
+ // constructor (before any container classloader swap), so reuse it here.
final JsonbBuilder jsonbBuilder = JsonbBuilder
- .newBuilder()
+ .newBuilder(jsonbProvider)
.withProvider(new PreComputedJsonpProvider(id, jsonpProvider, jsonpParserFactory, jsonpWriterFactory,
jsonpBuilderFactory,
new RecordJsonGenerator.Factory(Lazy.lazy(() -> recordBuilderFactoryProvider.apply(id)), jsonb,
emptyMap()),
jsonpReaderFactory))
.withConfig(jsonbConfig);
- try { // to passthrough the writer, otherwise RecoderJsonGenerator is broken
- final Field mapper = jsonbBuilder.getClass().getDeclaredField("builder");
- if (!mapper.isAccessible()) {
- mapper.setAccessible(true);
+ // to passthrough the writer, otherwise RecoderJsonGenerator is broken - only applies to the
+ // Johnzon JsonbBuilder implementation, other JSON-B providers (e.g. Yasson) don't expose this
+ // internal field and don't need the optimization
+ if (jsonbBuilder instanceof JohnzonBuilder) {
+ try {
+ final Field mapper = jsonbBuilder.getClass().getDeclaredField("builder");
+ if (!mapper.isAccessible()) {
+ mapper.setAccessible(true);
+ }
+ ((MapperBuilder) mapper.get(jsonbBuilder)).setDoCloseOnStreams(true);
+ } catch (final NoSuchFieldException | IllegalAccessException e) {
+ throw new IllegalStateException(e);
}
- ((MapperBuilder) mapper.get(jsonbBuilder)).setDoCloseOnStreams(true);
- } catch (final Exception e) {
- throw new IllegalStateException(e);
+ } else {
+ log.debug("JsonbBuilder implementation {} is not Johnzon's, skipping doCloseOnStreams optimization",
+ jsonbBuilder.getClass().getName());
}
return jsonbBuilder;
}
diff --git a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/DefaultServices.java b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/DefaultServices.java
index c7d9ef16156d9..2c805c19d36be 100644
--- a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/DefaultServices.java
+++ b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/DefaultServices.java
@@ -19,11 +19,11 @@
import java.util.function.Function;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonReaderFactory;
-import javax.json.JsonWriterFactory;
-import javax.json.stream.JsonGeneratorFactory;
-import javax.json.stream.JsonParserFactory;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonReaderFactory;
+import jakarta.json.JsonWriterFactory;
+import jakarta.json.stream.JsonGeneratorFactory;
+import jakarta.json.stream.JsonParserFactory;
import org.talend.sdk.component.api.service.record.RecordBuilderFactory;
import org.talend.sdk.component.runtime.manager.ComponentManager;
diff --git a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/GenericOrPojoJsonb.java b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/GenericOrPojoJsonb.java
index b038ad050653c..3adee3be066fd 100644
--- a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/GenericOrPojoJsonb.java
+++ b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/GenericOrPojoJsonb.java
@@ -25,8 +25,8 @@
import java.util.Objects;
import java.util.stream.Stream;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbException;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbException;
import org.talend.sdk.component.runtime.record.json.PojoJsonbProvider;
import org.talend.sdk.component.runtime.serialization.SerializableService;
diff --git a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/LocalCacheService.java b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/LocalCacheService.java
index 7ed61f9922ecd..c2e259273cb0e 100644
--- a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/LocalCacheService.java
+++ b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/LocalCacheService.java
@@ -31,7 +31,7 @@
import java.util.function.Supplier;
import java.util.stream.Stream;
-import javax.annotation.PreDestroy;
+import jakarta.annotation.PreDestroy;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.service.cache.LocalCache;
diff --git a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/RecordServiceImpl.java b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/RecordServiceImpl.java
index 6ab4f94345704..6355484b23238 100644
--- a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/RecordServiceImpl.java
+++ b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/RecordServiceImpl.java
@@ -30,9 +30,9 @@
import java.util.function.Supplier;
import java.util.stream.Collector;
-import javax.json.JsonBuilderFactory;
-import javax.json.bind.Jsonb;
-import javax.json.spi.JsonProvider;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.spi.JsonProvider;
import org.talend.sdk.component.api.record.Record;
import org.talend.sdk.component.api.record.Schema;
diff --git a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/http/HttpClientFactoryImpl.java b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/http/HttpClientFactoryImpl.java
index c5eb3d3ac9ecc..4702f6ffc3889 100644
--- a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/http/HttpClientFactoryImpl.java
+++ b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/http/HttpClientFactoryImpl.java
@@ -32,7 +32,7 @@
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Stream;
-import javax.json.bind.Jsonb;
+import jakarta.json.bind.Jsonb;
import org.talend.sdk.component.api.service.http.HttpClient;
import org.talend.sdk.component.api.service.http.HttpClientFactory;
diff --git a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/http/RequestParser.java b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/http/RequestParser.java
index 344c343fa91c3..d6a44f9db25db 100644
--- a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/http/RequestParser.java
+++ b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/http/RequestParser.java
@@ -47,7 +47,7 @@
import java.util.function.Function;
import java.util.stream.Stream;
-import javax.json.bind.Jsonb;
+import jakarta.json.bind.Jsonb;
import org.talend.sdk.component.api.service.http.Base;
import org.talend.sdk.component.api.service.http.Codec;
diff --git a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/http/codec/JsonpDecoder.java b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/http/codec/JsonpDecoder.java
index 0ba2c4a550e8f..11edb68e8f20f 100644
--- a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/http/codec/JsonpDecoder.java
+++ b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/http/codec/JsonpDecoder.java
@@ -18,7 +18,7 @@
import java.io.ByteArrayInputStream;
import java.lang.reflect.Type;
-import javax.json.bind.Jsonb;
+import jakarta.json.bind.Jsonb;
import org.talend.sdk.component.api.service.http.Decoder;
diff --git a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/http/codec/JsonpEncoder.java b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/http/codec/JsonpEncoder.java
index 0bf35eabb97f4..1c354466981f4 100644
--- a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/http/codec/JsonpEncoder.java
+++ b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/http/codec/JsonpEncoder.java
@@ -20,7 +20,7 @@
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
-import javax.json.bind.Jsonb;
+import jakarta.json.bind.Jsonb;
import org.talend.sdk.component.api.service.http.Encoder;
diff --git a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/xbean/converter/SchemaConverter.java b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/xbean/converter/SchemaConverter.java
index fb0b0b2348527..9c1ceda0e3e1a 100644
--- a/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/xbean/converter/SchemaConverter.java
+++ b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/xbean/converter/SchemaConverter.java
@@ -26,16 +26,16 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonNumber;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
-import javax.json.JsonReader;
-import javax.json.JsonString;
-import javax.json.JsonValue;
-import javax.json.spi.JsonProvider;
+import jakarta.json.Json;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonArrayBuilder;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonObjectBuilder;
+import jakarta.json.JsonReader;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
+import jakarta.json.spi.JsonProvider;
import org.apache.xbean.propertyeditor.AbstractConverter;
import org.talend.sdk.component.api.record.Schema;
diff --git a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/EnsurePojoMappingTest.java b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/EnsurePojoMappingTest.java
index 2a7cc8b637f5a..1a0c31ec434f2 100644
--- a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/EnsurePojoMappingTest.java
+++ b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/EnsurePojoMappingTest.java
@@ -17,10 +17,10 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
-import javax.json.bind.JsonbConfig;
-import javax.json.bind.annotation.JsonbPropertyOrder;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.bind.JsonbConfig;
+import jakarta.json.bind.annotation.JsonbPropertyOrder;
import org.junit.jupiter.api.Test;
import org.talend.sdk.component.runtime.manager.json.TalendAccessMode;
diff --git a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/ParameterModelServiceTest.java b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/ParameterModelServiceTest.java
index c24c1080ee864..3154356836624 100644
--- a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/ParameterModelServiceTest.java
+++ b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/ParameterModelServiceTest.java
@@ -26,8 +26,11 @@
import java.util.List;
import java.util.Map;
+import jakarta.json.JsonBuilderFactory;
+
import org.apache.xbean.propertyeditor.PropertyEditorRegistry;
import org.junit.jupiter.api.Test;
+import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.runtime.manager.reflect.ParameterModelService;
import org.talend.sdk.component.runtime.manager.reflect.parameterenricher.BaseParameterEnricher;
import org.talend.sdk.component.runtime.manager.service.LocalConfigurationService;
@@ -417,6 +420,20 @@ private void assertConfigFieldsModel(final String prefix, final ParameterMeta ma
}
}
+ @Test
+ void jakartaTypedParametersAreServices() throws NoSuchMethodException {
+ final List params = service.buildParameterMetas(
+ ParameterModelServiceTest.class.getDeclaredMethod("withJakartaService", JsonBuilderFactory.class,
+ String.class),
+ "def", context());
+ assertEquals(1, params.size());
+ assertEquals("name", params.get(0).getName());
+ }
+
+ static void withJakartaService(final JsonBuilderFactory factory, @Option("name") final String name) {
+ // no-op: only the signature is used
+ }
+
private BaseParameterEnricher.Context context() {
return new BaseParameterEnricher.Context(new LocalConfigurationService(emptyList(), "test"));
}
diff --git a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/ReflectionServiceTest.java b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/ReflectionServiceTest.java
index 31aa7a8885aeb..4c2de2962e580 100644
--- a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/ReflectionServiceTest.java
+++ b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/ReflectionServiceTest.java
@@ -49,9 +49,9 @@
import java.util.stream.IntStream;
import java.util.stream.Stream;
-import javax.json.Json;
-import javax.json.JsonObject;
-import javax.json.bind.JsonbBuilder;
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
+import jakarta.json.bind.JsonbBuilder;
import org.apache.xbean.propertyeditor.AbstractConverter;
import org.apache.xbean.propertyeditor.PropertyEditorRegistry;
diff --git a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/chain/JobTest.java b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/chain/JobTest.java
index c37acc0056e8c..5ae975ce2277e 100644
--- a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/chain/JobTest.java
+++ b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/chain/JobTest.java
@@ -30,7 +30,7 @@
import java.util.List;
import java.util.function.Supplier;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
diff --git a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/checkpoint/CheckpointInputTest.java b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/checkpoint/CheckpointInputTest.java
index 1f31d5f995ade..a8440095c1ba9 100644
--- a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/checkpoint/CheckpointInputTest.java
+++ b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/checkpoint/CheckpointInputTest.java
@@ -32,9 +32,9 @@
import java.util.function.Consumer;
import java.util.function.Supplier;
-import javax.json.JsonObject;
-import javax.json.bind.Jsonb;
-import javax.json.bind.spi.JsonbProvider;
+import jakarta.json.JsonObject;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.spi.JsonbProvider;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
diff --git a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/extension/test/mappings/custom/ProcessorWithDbMapping.java b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/extension/test/mappings/custom/ProcessorWithDbMapping.java
index 5eeeb26e6b168..99a245078e33f 100644
--- a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/extension/test/mappings/custom/ProcessorWithDbMapping.java
+++ b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/extension/test/mappings/custom/ProcessorWithDbMapping.java
@@ -19,7 +19,7 @@
import java.io.Serializable;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.component.DatabaseMapping;
import org.talend.sdk.component.api.configuration.Option;
diff --git a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/extension/test/mappings/mysql/ProcessorWithMySqlMapping.java b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/extension/test/mappings/mysql/ProcessorWithMySqlMapping.java
index 6d68d32e6467d..ffa77b07417d8 100644
--- a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/extension/test/mappings/mysql/ProcessorWithMySqlMapping.java
+++ b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/extension/test/mappings/mysql/ProcessorWithMySqlMapping.java
@@ -17,7 +17,7 @@
import java.io.Serializable;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.component.DatabaseMapping;
import org.talend.sdk.component.api.configuration.Option;
diff --git a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/extension/test/nomapping/ProcessorWithoutDbMapping.java b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/extension/test/nomapping/ProcessorWithoutDbMapping.java
index 6a13ac43e7c82..986aac2177c75 100644
--- a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/extension/test/nomapping/ProcessorWithoutDbMapping.java
+++ b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/extension/test/nomapping/ProcessorWithoutDbMapping.java
@@ -17,7 +17,7 @@
import java.io.Serializable;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.processor.AfterGroup;
diff --git a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/reflect/visibility/PayloadMapperTest.java b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/reflect/visibility/PayloadMapperTest.java
index 1ef8aa039b973..44da83250dabe 100644
--- a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/reflect/visibility/PayloadMapperTest.java
+++ b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/reflect/visibility/PayloadMapperTest.java
@@ -23,7 +23,7 @@
import java.util.Map;
import java.util.TreeMap;
-import javax.json.JsonValue;
+import jakarta.json.JsonValue;
import org.apache.xbean.propertyeditor.PropertyEditorRegistry;
import org.junit.jupiter.api.Test;
diff --git a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/reflect/visibility/VisibilityServiceTest.java b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/reflect/visibility/VisibilityServiceTest.java
index 744bdeae5a2eb..d572c2b26b637 100644
--- a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/reflect/visibility/VisibilityServiceTest.java
+++ b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/reflect/visibility/VisibilityServiceTest.java
@@ -22,8 +22,8 @@
import java.util.HashMap;
import java.util.Map;
-import javax.json.Json;
-import javax.json.spi.JsonProvider;
+import jakarta.json.Json;
+import jakarta.json.spi.JsonProvider;
import org.junit.jupiter.api.Test;
import org.talend.sdk.component.runtime.manager.ParameterMeta;
diff --git a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/service/DefaultServiceProviderTest.java b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/service/DefaultServiceProviderTest.java
new file mode 100644
index 0000000000000..7ad875b8facda
--- /dev/null
+++ b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/service/DefaultServiceProviderTest.java
@@ -0,0 +1,103 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.runtime.manager.service;
+
+import static java.util.Collections.emptyList;
+import static java.util.Collections.emptyMap;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+import java.lang.reflect.Proxy;
+import java.util.Map;
+
+import jakarta.json.Json;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.bind.JsonbConfig;
+import jakarta.json.bind.spi.JsonbProvider;
+import jakarta.json.spi.JsonProvider;
+
+import org.junit.jupiter.api.Test;
+import org.talend.sdk.component.api.record.RecordPointerFactory;
+import org.talend.sdk.component.api.service.Service;
+import org.talend.sdk.component.api.service.record.RecordBuilderFactory;
+import org.talend.sdk.component.runtime.manager.json.PreComputedJsonpProvider;
+import org.talend.sdk.component.runtime.record.RecordBuilderFactoryImpl;
+
+class DefaultServiceProviderTest {
+
+ private final RecordBuilderFactory factory = new RecordBuilderFactoryImpl(null);
+
+ private DefaultServiceProvider provider(final JsonbProvider jsonbProvider) {
+ return new DefaultServiceProvider(null, JsonProvider.provider(), Json.createGeneratorFactory(emptyMap()),
+ Json.createReaderFactory(emptyMap()), Json.createBuilderFactory(emptyMap()),
+ Json.createParserFactory(emptyMap()), Json.createWriterFactory(emptyMap()), new JsonbConfig(),
+ jsonbProvider, null, null, emptyList(), t -> factory, null);
+ }
+
+ private T lookup(final DefaultServiceProvider provider, final Class api) {
+ return provider.lookup("test", Thread.currentThread().getContextClassLoader(), null, null, api, null, null);
+ }
+
+ @Test
+ void jsonpProvider() {
+ assertInstanceOf(PreComputedJsonpProvider.class, lookup(provider(JsonbProvider.provider()), JsonProvider.class));
+ }
+
+ @Test
+ void simpleServices() {
+ final DefaultServiceProvider provider = provider(JsonbProvider.provider());
+ assertNotNull(lookup(provider, RecordBuilderFactory.class));
+ assertNotNull(lookup(provider, RecordPointerFactory.class));
+ assertNotNull(lookup(provider, ContainerInfo.class));
+ assertNull(lookup(provider, Service.class));
+ }
+
+ @Test
+ void jsonbWithJohnzon() throws Exception {
+ final Jsonb jsonb = lookup(provider(JsonbProvider.provider()), Jsonb.class);
+ assertNotNull(jsonb);
+ assertEquals("{\"a\":\"b\"}", jsonb.toJson(Map.of("a", "b")));
+ jsonb.close();
+ }
+
+ @Test
+ void jsonbWithNonJohnzonBuilder() throws Exception {
+ final JsonbProvider delegate = JsonbProvider.provider();
+ final JsonbProvider wrapping = new JsonbProvider() {
+
+ @Override
+ public JsonbBuilder create() {
+ return wrap(delegate.create());
+ }
+ };
+ final Jsonb jsonb = lookup(provider(wrapping), Jsonb.class);
+ assertNotNull(jsonb);
+ assertEquals("{\"a\":\"b\"}", jsonb.toJson(Map.of("a", "b")));
+ jsonb.close();
+ }
+
+ private static JsonbBuilder wrap(final JsonbBuilder builder) {
+ return (JsonbBuilder) Proxy
+ .newProxyInstance(DefaultServiceProviderTest.class.getClassLoader(),
+ new Class>[] { JsonbBuilder.class }, (proxy, method, args) -> {
+ final Object result = method.invoke(builder, args);
+ return result == builder ? proxy : result;
+ });
+ }
+}
diff --git a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/service/HttpClientFactoryImplTest.java b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/service/HttpClientFactoryImplTest.java
index c3a32e338a03f..7051c712e0de2 100644
--- a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/service/HttpClientFactoryImplTest.java
+++ b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/service/HttpClientFactoryImplTest.java
@@ -42,8 +42,7 @@
import java.util.Map;
import java.util.stream.Stream;
-import javax.json.bind.JsonbBuilder;
-
+import jakarta.json.bind.JsonbBuilder;
import jakarta.xml.bind.annotation.XmlRootElement;
import com.sun.net.httpserver.Headers;
diff --git a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/service/RecordServiceImplTest.java b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/service/RecordServiceImplTest.java
index 6e9de866e74ce..ad55eb05790aa 100644
--- a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/service/RecordServiceImplTest.java
+++ b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/service/RecordServiceImplTest.java
@@ -34,10 +34,10 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;
-import javax.json.Json;
-import javax.json.bind.JsonbConfig;
-import javax.json.bind.spi.JsonbProvider;
-import javax.json.spi.JsonProvider;
+import jakarta.json.Json;
+import jakarta.json.bind.JsonbConfig;
+import jakarta.json.bind.spi.JsonbProvider;
+import jakarta.json.spi.JsonProvider;
import org.junit.jupiter.api.Test;
import org.talend.sdk.component.api.record.Record;
diff --git a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/service/http/RequestParserTest.java b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/service/http/RequestParserTest.java
index ca9ff86d1316d..e6077b6956612 100644
--- a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/service/http/RequestParserTest.java
+++ b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/service/http/RequestParserTest.java
@@ -20,8 +20,8 @@
import java.util.HashMap;
import java.util.Map;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
diff --git a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/xbean/converter/SchemaConverterTest.java b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/xbean/converter/SchemaConverterTest.java
index 5cc46cac99ce0..e74d5177650ef 100644
--- a/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/xbean/converter/SchemaConverterTest.java
+++ b/component-runtime-manager/src/test/java/org/talend/sdk/component/runtime/manager/xbean/converter/SchemaConverterTest.java
@@ -22,9 +22,9 @@
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicLong;
-import javax.json.JsonNumber;
-import javax.json.JsonObject;
-import javax.json.JsonValue;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonValue;
import org.junit.jupiter.api.Test;
import org.talend.sdk.component.api.record.Schema;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithAdvancedGridLayoutConfig.java b/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithAdvancedGridLayoutConfig.java
index 9d74caf10e813..bc2c6040ce8fb 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithAdvancedGridLayoutConfig.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithAdvancedGridLayoutConfig.java
@@ -17,7 +17,7 @@
import java.io.Serializable;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.configuration.ui.layout.GridLayout;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithAutoLayoutConfig.java b/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithAutoLayoutConfig.java
index ecce02ba62abb..901bbd835581c 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithAutoLayoutConfig.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithAutoLayoutConfig.java
@@ -17,7 +17,7 @@
import java.io.Serializable;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.configuration.ui.layout.AutoLayout;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithGridLayoutConfig.java b/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithGridLayoutConfig.java
index c06fa123712b6..ec42ab12a7529 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithGridLayoutConfig.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithGridLayoutConfig.java
@@ -17,7 +17,7 @@
import java.io.Serializable;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.configuration.ui.layout.GridLayout;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithHorizontalLayoutConfig.java b/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithHorizontalLayoutConfig.java
index 7d001a98a5ccf..c0591405ffa9d 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithHorizontalLayoutConfig.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithHorizontalLayoutConfig.java
@@ -17,7 +17,7 @@
import java.io.Serializable;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.configuration.ui.layout.HorizontalLayout;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithNoConfig.java b/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithNoConfig.java
index 9532adaa30f28..7593c81eb0c01 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithNoConfig.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithNoConfig.java
@@ -17,7 +17,7 @@
import java.io.Serializable;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.processor.AfterGroup;
import org.talend.sdk.component.api.processor.ElementListener;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithOptionOrderConfig.java b/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithOptionOrderConfig.java
index 8ef2b753317a0..97583c25430be 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithOptionOrderConfig.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithOptionOrderConfig.java
@@ -17,7 +17,7 @@
import java.io.Serializable;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.configuration.ui.OptionsOrder;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithVerticalLayoutConfig.java b/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithVerticalLayoutConfig.java
index 1580f680da00b..b2540454010d8 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithVerticalLayoutConfig.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithVerticalLayoutConfig.java
@@ -17,7 +17,7 @@
import java.io.Serializable;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.configuration.ui.layout.VerticalLayout;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithoutAfterGroup.java b/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithoutAfterGroup.java
index 890eaea0ffd67..3b8b83c540416 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithoutAfterGroup.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithoutAfterGroup.java
@@ -17,7 +17,7 @@
import java.io.Serializable;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.processor.ElementListener;
import org.talend.sdk.component.api.processor.Input;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithoutLayout.java b/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithoutLayout.java
index 5f70163b2ff75..f5b916a90729a 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithoutLayout.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/BulkProcessorWithoutLayout.java
@@ -17,7 +17,7 @@
import java.io.Serializable;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.processor.AfterGroup;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/CheckpointInput.java b/component-runtime-manager/src/test/java/org/talend/test/CheckpointInput.java
index 72e8674ee00ee..3c24923e4ba0c 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/CheckpointInput.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/CheckpointInput.java
@@ -21,11 +21,11 @@
import java.util.ListIterator;
import java.util.stream.IntStream;
-import javax.annotation.PostConstruct;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonObject;
-import javax.json.bind.Jsonb;
-import javax.json.bind.annotation.JsonbProperty;
+import jakarta.annotation.PostConstruct;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.annotation.JsonbProperty;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.configuration.ui.layout.GridLayout;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/ConcatProcessor.java b/component-runtime-manager/src/test/java/org/talend/test/ConcatProcessor.java
index dcd8f486999ce..4a3852c0273bc 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/ConcatProcessor.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/ConcatProcessor.java
@@ -17,9 +17,9 @@
import java.io.Serializable;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonObjectBuilder;
import org.talend.sdk.component.api.processor.ElementListener;
import org.talend.sdk.component.api.processor.Input;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/CounterProcessor.java b/component-runtime-manager/src/test/java/org/talend/test/CounterProcessor.java
index bf99f7a1a5dad..a914544860e16 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/CounterProcessor.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/CounterProcessor.java
@@ -17,8 +17,8 @@
import java.io.Serializable;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonObject;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.processor.ElementListener;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/DataInput.java b/component-runtime-manager/src/test/java/org/talend/test/DataInput.java
index ed8e64ae3bfcd..cd4bd40171c50 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/DataInput.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/DataInput.java
@@ -22,8 +22,8 @@
import java.util.List;
import java.util.Map;
-import javax.json.JsonObject;
-import javax.json.bind.Jsonb;
+import jakarta.json.JsonObject;
+import jakarta.json.bind.Jsonb;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.input.Emitter;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/FileOutput.java b/component-runtime-manager/src/test/java/org/talend/test/FileOutput.java
index d584d4b31f2c9..957419d79b80f 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/FileOutput.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/FileOutput.java
@@ -25,8 +25,8 @@
import java.util.List;
import java.util.Locale;
-import javax.annotation.PreDestroy;
-import javax.json.JsonObject;
+import jakarta.annotation.PreDestroy;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.configuration.ui.layout.AutoLayout;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/FormatterProcessor.java b/component-runtime-manager/src/test/java/org/talend/test/FormatterProcessor.java
index a3528d8554ddc..5a49b299c12a9 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/FormatterProcessor.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/FormatterProcessor.java
@@ -18,9 +18,9 @@
import java.io.Serializable;
import java.util.Locale;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonObjectBuilder;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.processor.ElementListener;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/InMemCollector.java b/component-runtime-manager/src/test/java/org/talend/test/InMemCollector.java
index f698444710f9d..967b3ba58d060 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/InMemCollector.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/InMemCollector.java
@@ -19,7 +19,7 @@
import java.util.ArrayList;
import java.util.Collection;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.processor.ElementListener;
import org.talend.sdk.component.api.processor.Processor;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/InfiniteMapper.java b/component-runtime-manager/src/test/java/org/talend/test/InfiniteMapper.java
index e9512c5efbadb..e6ede4587f520 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/InfiniteMapper.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/InfiniteMapper.java
@@ -19,7 +19,7 @@
import java.io.Serializable;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.input.Assessor;
import org.talend.sdk.component.api.input.Emitter;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/InfiniteStoppableMapper.java b/component-runtime-manager/src/test/java/org/talend/test/InfiniteStoppableMapper.java
index 4054febd95931..b7217a55b3eab 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/InfiniteStoppableMapper.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/InfiniteStoppableMapper.java
@@ -19,7 +19,7 @@
import java.io.Serializable;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.input.Assessor;
import org.talend.sdk.component.api.input.Emitter;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/InjectedConfigComponent.java b/component-runtime-manager/src/test/java/org/talend/test/InjectedConfigComponent.java
index 649f222bca97d..223099d3152b8 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/InjectedConfigComponent.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/InjectedConfigComponent.java
@@ -20,8 +20,8 @@
import java.io.Serializable;
import java.util.Iterator;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonObject;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.input.Emitter;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/LifecycleCountDownInput.java b/component-runtime-manager/src/test/java/org/talend/test/LifecycleCountDownInput.java
index b1807cd63c6a6..e19a6877cf8e7 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/LifecycleCountDownInput.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/LifecycleCountDownInput.java
@@ -25,10 +25,10 @@
import java.util.function.Supplier;
import java.util.stream.IntStream;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonObject;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.input.Emitter;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/LifecycleSquareProcessor.java b/component-runtime-manager/src/test/java/org/talend/test/LifecycleSquareProcessor.java
index ae637acbc2ab2..4dbdba59d8205 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/LifecycleSquareProcessor.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/LifecycleSquareProcessor.java
@@ -20,10 +20,10 @@
import java.util.List;
import java.util.function.Supplier;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonObject;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.processor.AfterGroup;
import org.talend.sdk.component.api.processor.BeforeGroup;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/MapperWithCheckpoint.java b/component-runtime-manager/src/test/java/org/talend/test/MapperWithCheckpoint.java
index 498f4842acaeb..a2b05a7d3c834 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/MapperWithCheckpoint.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/MapperWithCheckpoint.java
@@ -19,7 +19,7 @@
import java.util.ArrayList;
import java.util.List;
-import javax.json.bind.annotation.JsonbProperty;
+import jakarta.json.bind.annotation.JsonbProperty;
import org.talend.sdk.component.api.component.Version;
import org.talend.sdk.component.api.configuration.Option;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/RejectOutput.java b/component-runtime-manager/src/test/java/org/talend/test/RejectOutput.java
index b9b8346a1c219..283f27a76b667 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/RejectOutput.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/RejectOutput.java
@@ -21,8 +21,8 @@
import java.io.Serializable;
import java.io.Writer;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.processor.ElementListener;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/ResumeableInput.java b/component-runtime-manager/src/test/java/org/talend/test/ResumeableInput.java
index de6c6ad6e65c9..0d1cf12200c43 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/ResumeableInput.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/ResumeableInput.java
@@ -27,8 +27,8 @@
import java.util.ListIterator;
import java.util.Map;
-import javax.annotation.PostConstruct;
-import javax.json.bind.Jsonb;
+import jakarta.annotation.PostConstruct;
+import jakarta.json.bind.Jsonb;
import org.talend.sdk.component.api.component.MigrationHandler;
import org.talend.sdk.component.api.component.Version;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/ResumeableMapper.java b/component-runtime-manager/src/test/java/org/talend/test/ResumeableMapper.java
index a6784d29ebbe9..36df5caa96c0e 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/ResumeableMapper.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/ResumeableMapper.java
@@ -19,7 +19,7 @@
import java.util.Collections;
import java.util.List;
-import javax.json.bind.Jsonb;
+import jakarta.json.bind.Jsonb;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.input.Assessor;
diff --git a/component-runtime-manager/src/test/java/org/talend/test/SingleInput.java b/component-runtime-manager/src/test/java/org/talend/test/SingleInput.java
index b5d4c797edf37..9e0b87a82a905 100644
--- a/component-runtime-manager/src/test/java/org/talend/test/SingleInput.java
+++ b/component-runtime-manager/src/test/java/org/talend/test/SingleInput.java
@@ -17,8 +17,8 @@
import java.io.Serializable;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonObject;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.input.Emitter;
import org.talend.sdk.component.api.input.Producer;
diff --git a/component-runtime-testing/component-runtime-beam-junit/src/main/java/org/talend/sdk/component/junit/beam/Data.java b/component-runtime-testing/component-runtime-beam-junit/src/main/java/org/talend/sdk/component/junit/beam/Data.java
index b03e2f9626e2a..3f4bb17e7164d 100644
--- a/component-runtime-testing/component-runtime-beam-junit/src/main/java/org/talend/sdk/component/junit/beam/Data.java
+++ b/component-runtime-testing/component-runtime-beam-junit/src/main/java/org/talend/sdk/component/junit/beam/Data.java
@@ -26,10 +26,10 @@
import java.util.List;
import java.util.Map;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonObject;
-import javax.json.bind.Jsonb;
-import javax.json.spi.JsonProvider;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.spi.JsonProvider;
import org.apache.beam.sdk.coders.Coder;
import org.apache.beam.sdk.coders.MapCoder;
diff --git a/component-runtime-testing/component-runtime-beam-junit/src/test/java/org/talend/sdk/component/junit/beam/ProcessorTest.java b/component-runtime-testing/component-runtime-beam-junit/src/test/java/org/talend/sdk/component/junit/beam/ProcessorTest.java
index 41c6a7021f01c..c99f53c400433 100644
--- a/component-runtime-testing/component-runtime-beam-junit/src/test/java/org/talend/sdk/component/junit/beam/ProcessorTest.java
+++ b/component-runtime-testing/component-runtime-beam-junit/src/test/java/org/talend/sdk/component/junit/beam/ProcessorTest.java
@@ -25,7 +25,7 @@
import java.util.Map;
import java.util.stream.StreamSupport;
-import javax.json.Json;
+import jakarta.json.Json;
import org.apache.beam.sdk.PipelineResult;
import org.apache.beam.sdk.testing.PAssert;
diff --git a/component-runtime-testing/component-runtime-http-junit/pom.xml b/component-runtime-testing/component-runtime-http-junit/pom.xml
index a45981ac850e6..9df24f94b6c90 100644
--- a/component-runtime-testing/component-runtime-http-junit/pom.xml
+++ b/component-runtime-testing/component-runtime-http-junit/pom.xml
@@ -38,21 +38,22 @@
slf4j-api
+
- org.apache.geronimo.specs
- geronimo-jsonb_1.0_spec
- ${geronimo-jsonb.version}
+ jakarta.json.bind
+ jakarta.json.bind-api
true
- org.apache.geronimo.specs
- geronimo-json_1.1_spec
- ${geronimo-json.version}
+ jakarta.json
+ jakarta.json-api
true
org.apache.johnzon
johnzon-jsonb
+ ${johnzon.version}
true
@@ -175,7 +176,8 @@
io.netty:*
- org.apache.geronimo.specs:*
+ jakarta.json:*
+ jakarta.json.bind:*
org.apache.johnzon:*
@@ -189,8 +191,8 @@
org.talend.__shade__.org.apache.johnzon
- javax.json
- org.talend.__shade__.javax.json
+ jakarta.json
+ org.talend.__shade__.jakarta.json
diff --git a/component-runtime-testing/component-runtime-http-junit/src/main/java/org/talend/sdk/component/junit/http/internal/impl/DefaultResponseLocator.java b/component-runtime-testing/component-runtime-http-junit/src/main/java/org/talend/sdk/component/junit/http/internal/impl/DefaultResponseLocator.java
index 213b75e7a8fe2..c793b653c754d 100644
--- a/component-runtime-testing/component-runtime-http-junit/src/main/java/org/talend/sdk/component/junit/http/internal/impl/DefaultResponseLocator.java
+++ b/component-runtime-testing/component-runtime-http-junit/src/main/java/org/talend/sdk/component/junit/http/internal/impl/DefaultResponseLocator.java
@@ -38,10 +38,10 @@
import java.util.function.Predicate;
import java.util.stream.Stream;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
-import javax.json.bind.JsonbConfig;
-import javax.json.bind.config.PropertyOrderStrategy;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.bind.JsonbConfig;
+import jakarta.json.bind.config.PropertyOrderStrategy;
import org.talend.sdk.component.junit.http.api.Request;
import org.talend.sdk.component.junit.http.api.Response;
diff --git a/component-runtime-testing/component-runtime-http-junit/src/test/java/org/talend/sdk/component/junit/http/test/json/AssertJson.java b/component-runtime-testing/component-runtime-http-junit/src/test/java/org/talend/sdk/component/junit/http/test/json/AssertJson.java
index 10fb3f9920538..c7713198e4472 100644
--- a/component-runtime-testing/component-runtime-http-junit/src/test/java/org/talend/sdk/component/junit/http/test/json/AssertJson.java
+++ b/component-runtime-testing/component-runtime-http-junit/src/test/java/org/talend/sdk/component/junit/http/test/json/AssertJson.java
@@ -19,9 +19,9 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
-import javax.json.JsonValue;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
+import jakarta.json.JsonValue;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
import lombok.NoArgsConstructor;
diff --git a/component-runtime-testing/component-runtime-junit/pom.xml b/component-runtime-testing/component-runtime-junit/pom.xml
index 0b92fe6622c2f..714f06fb5db1e 100644
--- a/component-runtime-testing/component-runtime-junit/pom.xml
+++ b/component-runtime-testing/component-runtime-junit/pom.xml
@@ -178,6 +178,18 @@
org/junit/jupiter/api/extension/TestInstantiationAwareExtension
org.junit.jupiter.api.extension.TestInstantiationAwareExtension has been removed by junit5, not by our code
+
+
+ org/talend/sdk/component/junit/BaseComponentsHandler$State
+ 7005
+ BaseComponentsHandler$State(org.talend.sdk.component.runtime.manager.ComponentManager, java.util.Collection, java.util.Iterator, javax.json.bind.Jsonb, javax.json.spi.JsonProvider, javax.json.JsonBuilderFactory, org.talend.sdk.component.api.service.record.RecordBuilderFactory)
+ BaseComponentsHandler$State(org.talend.sdk.component.runtime.manager.ComponentManager, java.util.Collection, java.util.Iterator, jakarta.json.bind.Jsonb, jakarta.json.spi.JsonProvider, jakarta.json.JsonBuilderFactory, org.talend.sdk.component.api.service.record.RecordBuilderFactory)
+ QTDI-3497: State constructor moved to jakarta.json/jakarta.json.bind, breaking on purpose
+
diff --git a/component-runtime-testing/component-runtime-junit/src/main/java/org/talend/sdk/component/junit/BaseComponentsHandler.java b/component-runtime-testing/component-runtime-junit/src/main/java/org/talend/sdk/component/junit/BaseComponentsHandler.java
index d990259660ffe..05209efffd64c 100644
--- a/component-runtime-testing/component-runtime-junit/src/main/java/org/talend/sdk/component/junit/BaseComponentsHandler.java
+++ b/component-runtime-testing/component-runtime-junit/src/main/java/org/talend/sdk/component/junit/BaseComponentsHandler.java
@@ -54,11 +54,11 @@
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonObject;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbConfig;
-import javax.json.spi.JsonProvider;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbConfig;
+import jakarta.json.spi.JsonProvider;
import org.apache.xbean.finder.filter.Filter;
import org.talend.sdk.component.api.record.Record;
diff --git a/component-runtime-testing/component-runtime-junit/src/main/java/org/talend/sdk/component/junit/JoinInputFactory.java b/component-runtime-testing/component-runtime-junit/src/main/java/org/talend/sdk/component/junit/JoinInputFactory.java
index 8148a7df18ea1..45f6c5c073ba5 100644
--- a/component-runtime-testing/component-runtime-junit/src/main/java/org/talend/sdk/component/junit/JoinInputFactory.java
+++ b/component-runtime-testing/component-runtime-junit/src/main/java/org/talend/sdk/component/junit/JoinInputFactory.java
@@ -20,9 +20,9 @@
import java.util.Iterator;
import java.util.Map;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
-import javax.json.bind.JsonbConfig;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+import jakarta.json.bind.JsonbConfig;
import org.talend.sdk.component.api.record.Record;
import org.talend.sdk.component.runtime.manager.ComponentManager;
diff --git a/component-runtime-testing/component-runtime-junit/src/test/java/org/talend/sdk/component/junit/JoinInputFactoryTest.java b/component-runtime-testing/component-runtime-junit/src/test/java/org/talend/sdk/component/junit/JoinInputFactoryTest.java
index f9a0cd99dd94d..b098f8df7e711 100644
--- a/component-runtime-testing/component-runtime-junit/src/test/java/org/talend/sdk/component/junit/JoinInputFactoryTest.java
+++ b/component-runtime-testing/component-runtime-junit/src/test/java/org/talend/sdk/component/junit/JoinInputFactoryTest.java
@@ -21,7 +21,7 @@
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import javax.json.Json;
+import jakarta.json.Json;
import org.junit.jupiter.api.Test;
import org.talend.sdk.component.api.record.Record;
diff --git a/component-runtime-testing/component-runtime-junit/src/test/java/org/talend/sdk/component/junit/SimpleComponentRuleTest.java b/component-runtime-testing/component-runtime-junit/src/test/java/org/talend/sdk/component/junit/SimpleComponentRuleTest.java
index a12cbac2c6fb3..a3c7b2a62bb5c 100644
--- a/component-runtime-testing/component-runtime-junit/src/test/java/org/talend/sdk/component/junit/SimpleComponentRuleTest.java
+++ b/component-runtime-testing/component-runtime-junit/src/test/java/org/talend/sdk/component/junit/SimpleComponentRuleTest.java
@@ -30,9 +30,9 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Stream;
-import javax.json.Json;
-import javax.json.JsonObject;
-import javax.json.bind.Jsonb;
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
+import jakarta.json.bind.Jsonb;
import org.junit.Assert;
import org.junit.ClassRule;
diff --git a/component-runtime-testing/component-runtime-junit/src/test/java/org/talend/sdk/component/junit5/ComponentExtensionTest.java b/component-runtime-testing/component-runtime-junit/src/test/java/org/talend/sdk/component/junit5/ComponentExtensionTest.java
index 584052325e380..d69e02f0a06c0 100644
--- a/component-runtime-testing/component-runtime-junit/src/test/java/org/talend/sdk/component/junit5/ComponentExtensionTest.java
+++ b/component-runtime-testing/component-runtime-junit/src/test/java/org/talend/sdk/component/junit5/ComponentExtensionTest.java
@@ -29,7 +29,7 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Stream;
-import javax.json.bind.Jsonb;
+import jakarta.json.bind.Jsonb;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
diff --git a/component-server-parent/component-server-api/pom.xml b/component-server-parent/component-server-api/pom.xml
index 1113cf5aea8c1..694f7361d9702 100644
--- a/component-server-parent/component-server-api/pom.xml
+++ b/component-server-parent/component-server-api/pom.xml
@@ -33,9 +33,8 @@
- org.apache.geronimo.specs
- geronimo-jaxrs_2.1_spec
- ${geronimo-jaxrs.version}
+ jakarta.ws.rs
+ jakarta.ws.rs-api
provided
diff --git a/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/ActionResource.java b/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/ActionResource.java
index a4ec80b547fdc..30aa30af4b293 100644
--- a/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/ActionResource.java
+++ b/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/ActionResource.java
@@ -15,7 +15,7 @@
*/
package org.talend.sdk.component.server.api;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.eclipse.microprofile.openapi.annotations.enums.ParameterIn.QUERY;
import static org.eclipse.microprofile.openapi.annotations.enums.SchemaType.OBJECT;
import static org.eclipse.microprofile.openapi.annotations.enums.SchemaType.STRING;
@@ -23,14 +23,14 @@
import java.util.Map;
import java.util.concurrent.CompletionStage;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.Response;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.DefaultValue;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.media.Content;
diff --git a/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/BulkReadResource.java b/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/BulkReadResource.java
index 58654b9b5a1ab..e8e2709e44fa7 100644
--- a/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/BulkReadResource.java
+++ b/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/BulkReadResource.java
@@ -15,14 +15,14 @@
*/
package org.talend.sdk.component.server.api;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
import java.util.concurrent.CompletionStage;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.media.Content;
diff --git a/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/CacheResource.java b/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/CacheResource.java
index 185f0963e7316..6cd135f379031 100644
--- a/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/CacheResource.java
+++ b/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/CacheResource.java
@@ -15,10 +15,10 @@
*/
package org.talend.sdk.component.server.api;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.media.Content;
diff --git a/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/ComponentResource.java b/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/ComponentResource.java
index 9922127b9baa2..5b4bab6464a64 100644
--- a/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/ComponentResource.java
+++ b/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/ComponentResource.java
@@ -15,8 +15,8 @@
*/
package org.talend.sdk.component.server.api;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM;
import static org.eclipse.microprofile.openapi.annotations.enums.ParameterIn.PATH;
import static org.eclipse.microprofile.openapi.annotations.enums.ParameterIn.QUERY;
import static org.eclipse.microprofile.openapi.annotations.enums.SchemaType.OBJECT;
@@ -24,17 +24,17 @@
import java.util.Map;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.StreamingOutput;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.DefaultValue;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.StreamingOutput;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.media.Content;
diff --git a/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/ConfigurationTypeResource.java b/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/ConfigurationTypeResource.java
index cd6f9b37abf88..22818a3064d56 100644
--- a/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/ConfigurationTypeResource.java
+++ b/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/ConfigurationTypeResource.java
@@ -15,7 +15,7 @@
*/
package org.talend.sdk.component.server.api;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.eclipse.microprofile.openapi.annotations.enums.ParameterIn.PATH;
import static org.eclipse.microprofile.openapi.annotations.enums.ParameterIn.QUERY;
import static org.eclipse.microprofile.openapi.annotations.enums.SchemaType.BOOLEAN;
@@ -24,14 +24,14 @@
import java.util.Map;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.DefaultValue;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.media.Content;
diff --git a/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/DocumentationResource.java b/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/DocumentationResource.java
index 28fc2f9d743e2..99bab9966ac40 100644
--- a/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/DocumentationResource.java
+++ b/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/DocumentationResource.java
@@ -15,19 +15,19 @@
*/
package org.talend.sdk.component.server.api;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.eclipse.microprofile.openapi.annotations.enums.ParameterIn.PATH;
import static org.eclipse.microprofile.openapi.annotations.enums.ParameterIn.QUERY;
import static org.eclipse.microprofile.openapi.annotations.enums.SchemaType.OBJECT;
import static org.eclipse.microprofile.openapi.annotations.enums.SchemaType.STRING;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
+import jakarta.ws.rs.DefaultValue;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.core.MediaType;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.media.Content;
diff --git a/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/EnvironmentResource.java b/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/EnvironmentResource.java
index 697c20b1cd97f..84625e8e06561 100644
--- a/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/EnvironmentResource.java
+++ b/component-server-parent/component-server-api/src/main/java/org/talend/sdk/component/server/api/EnvironmentResource.java
@@ -15,10 +15,10 @@
*/
package org.talend.sdk.component.server.api;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.media.Content;
diff --git a/component-server-parent/component-server-model/pom.xml b/component-server-parent/component-server-model/pom.xml
index 777767cebc904..df320d08ddcaa 100644
--- a/component-server-parent/component-server-model/pom.xml
+++ b/component-server-parent/component-server-model/pom.xml
@@ -37,9 +37,8 @@
- org.apache.geronimo.specs
- geronimo-json_1.1_spec
- ${geronimo-json.version}
+ jakarta.json
+ jakarta.json-api
diff --git a/component-server-parent/component-server-model/src/main/java/org/talend/sdk/component/server/front/model/BulkResponses.java b/component-server-parent/component-server-model/src/main/java/org/talend/sdk/component/server/front/model/BulkResponses.java
index 258214dd726fd..467d9b6541739 100644
--- a/component-server-parent/component-server-model/src/main/java/org/talend/sdk/component/server/front/model/BulkResponses.java
+++ b/component-server-parent/component-server-model/src/main/java/org/talend/sdk/component/server/front/model/BulkResponses.java
@@ -18,7 +18,7 @@
import java.util.List;
import java.util.Map;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import lombok.AllArgsConstructor;
import lombok.Data;
diff --git a/component-server-parent/component-server/module-knowledge.md b/component-server-parent/component-server/module-knowledge.md
new file mode 100644
index 0000000000000..29f56c53d4c69
--- /dev/null
+++ b/component-server-parent/component-server/module-knowledge.md
@@ -0,0 +1,20 @@
+# Module knowledge — component-server
+
+## Surefire fork isolation
+
+### A `reuseForks=false` fix for one surefire execution does not extend to sibling executions in the same pom
+
+[2026-09-22 | QTDI-3358] `component-server`'s `pom.xml` has two `maven-surefire-plugin` executions
+in the `test` phase — `default-test` and `beam-sample-test` — both of which start a
+`ComponentManager`/Meecrowave container keyed by a fixed test container id
+(`the-test-component`). Round 0 of this ticket's jakarta migration added
+`false` to `default-test` to stop a `Container '...' already exists`
+collision between test classes sharing one JVM fork, but did not extend the same fix to
+`beam-sample-test` — which runs `BeamActionSerializationTest` and `BeamComponentResourceImplTest`
+back-to-back and hit the identical collision on CI (intermittent, since it depends on Meecrowave
+teardown timing relative to the next test class's startup — not reliably reproduced locally).
+**Fix applied**: add the same `false` to `beam-sample-test`'s
+``. **Takeaway**: when this class of container-id collision shows up in one
+surefire execution of this pom, check every execution that boots a `ComponentManager`/Meecrowave
+instance with a shared/fixed container id — the collision risk is per-execution, not per-pom, and
+a partial fix (one execution only) leaves the others exposed.
diff --git a/component-server-parent/component-server/pom.xml b/component-server-parent/component-server/pom.xml
index c24347d675b59..9411c2978b6b3 100644
--- a/component-server-parent/component-server/pom.xml
+++ b/component-server-parent/component-server/pom.xml
@@ -42,11 +42,13 @@
org.talend.sdk.component
component-runtime-manager
${project.version}
+
-
- org.apache.geronimo.specs
- geronimo-annotation_1.3_spec
-
org.apache.geronimo.specs
geronimo-json_1.1_spec
@@ -78,10 +80,25 @@
commons-cli
${commons-cli.version}
-
+
org.apache.johnzon
johnzon-jsonb
+ ${johnzon.version}
+
+
+
+ org.glassfish
+ javax.json
+
+
+ org.eclipse
+ yasson
org.apache.commons
@@ -104,8 +121,8 @@
provided
- org.apache.geronimo.config
- geronimo-config-impl
+ io.smallrye.config
+ smallrye-config
org.apache.logging.log4j
@@ -158,6 +175,20 @@
${meecrowave.version}
test
+
+ org.mockito
+ mockito-junit-jupiter
+ test
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+
+
+
org.apache.tomee
ziplock
@@ -392,7 +423,7 @@
false
-1
- apiguardian,brave,kafka,lz4,talend-icon,zipkin,container-core,component-runtime,beam,paranamer,joda-time,avro,objenesis,xz,snappy,component-spi,component-api,tomcat-websocket
+ apiguardian,brave,kafka,lz4,talend-icon,zipkin,container-core,component-runtime,beam,paranamer,joda-time,avro,objenesis,xz,snappy,component-spi,component-api,tomcat-websocket,smallrye-config
+ https://jakarta.ee/xml/ns/jakartaee
+ https://jakarta.ee/xml/ns/jakartaee/beans_4_0.xsd"/>
diff --git a/component-server-parent/component-server/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension b/component-server-parent/component-server/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension
new file mode 100644
index 0000000000000..f87a889621277
--- /dev/null
+++ b/component-server-parent/component-server/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension
@@ -0,0 +1,2 @@
+org.talend.sdk.component.server.configuration.ComponentConfigurationLoader$Init
+org.talend.sdk.component.server.service.jcache.cdi.MakeJCacheCDIInterceptorFriendly
diff --git a/component-server-parent/component-server/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/component-server-parent/component-server/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
deleted file mode 100644
index 31ad38e4d0ba7..0000000000000
--- a/component-server-parent/component-server/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
+++ /dev/null
@@ -1 +0,0 @@
-org.talend.sdk.component.server.configuration.ComponentConfigurationLoader$Init
diff --git a/component-server-parent/component-server/src/main/resources/meecrowave.properties b/component-server-parent/component-server/src/main/resources/meecrowave.properties
index 3a7269ed4762d..4e1415aeb4a13 100644
--- a/component-server-parent/component-server/src/main/resources/meecrowave.properties
+++ b/component-server-parent/component-server/src/main/resources/meecrowave.properties
@@ -13,9 +13,13 @@
# limitations under the License.
# jars which don't need to be scanned (optional config but makes logs easier to read and startup a bit faster)
+# smallrye-config is excluded to avoid an AmbiguousResolutionException: its own portable extension
+# already registers io.smallrye.config.inject.ConfigProducer as a synthetic bean, so implicit CDI
+# scanning of the same class produces a duplicate bean for every @ConfigProperty injection point
+# (QTDI-3358 jakarta migration).
scanning-exclude = apiguardian,brave,kafka,lz4,talend-icon,zipkin,container-core,component-runtime,\
beam,paranamer,joda-time,avro,objenesis,xz,snappy,component-spi,component-api,tomcat-websocket,org.osgi,org.jacoco,sigar,\
-dirgra,bytelist,invokebinder,jcodings,joni,modulator,options,common-java5,zstd-jni,beam-vendor,beam-runners
+dirgra,bytelist,invokebinder,jcodings,joni,modulator,options,common-java5,zstd-jni,beam-vendor,beam-runners,smallrye-config
watcher-bouncing = -1
# gzip support
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/ActionResourceImplTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/ActionResourceImplTest.java
index 2ef141529f2ae..4dc225fe3f964 100644
--- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/ActionResourceImplTest.java
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/ActionResourceImplTest.java
@@ -15,8 +15,8 @@
*/
package org.talend.sdk.component.server.front;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static java.util.Collections.emptyMap;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -31,18 +31,19 @@
import java.util.List;
import java.util.Map;
-import javax.inject.Inject;
-import javax.json.JsonObject;
-import javax.json.bind.spi.JsonbProvider;
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.GenericType;
-import javax.ws.rs.core.Response;
+import jakarta.inject.Inject;
+import jakarta.json.JsonObject;
+import jakarta.json.bind.spi.JsonbProvider;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.GenericType;
+import jakarta.ws.rs.core.Response;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.talend.sdk.component.api.record.Schema;
@@ -54,7 +55,12 @@
import org.talend.sdk.component.server.front.model.ErrorDictionary;
import org.talend.sdk.component.server.front.model.error.ErrorPayload;
-@MonoMeecrowaveConfig
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+// jsonbPrettify=true restores what InitTestInfra's Meecrowave.ConfigurationCustomizer already sets: any
+// @MeecrowaveConfig-annotated test unconditionally re-applies every annotation attribute - including
+// jsonbPrettify's own "false" default - onto the builder via reflection, silently overriding the
+// customizer once a test stops using @MonoMeecrowaveConfig (which never applies annotation attributes at all).
+@MeecrowaveConfig(scanningExcludes = "smallrye-config", jsonbPrettify = true)
class ActionResourceImplTest {
@Inject
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/BulkReadResourceImplTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/BulkReadResourceImplTest.java
index de1c518fdee41..a8b583b35994e 100644
--- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/BulkReadResourceImplTest.java
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/BulkReadResourceImplTest.java
@@ -15,13 +15,13 @@
*/
package org.talend.sdk.component.server.front;
+import static jakarta.ws.rs.client.Entity.entity;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
-import static javax.ws.rs.client.Entity.entity;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -29,21 +29,23 @@
import java.util.List;
import java.util.stream.IntStream;
-import javax.inject.Inject;
-import javax.json.bind.Jsonb;
-import javax.servlet.http.HttpServletResponse;
-import javax.ws.rs.HttpMethod;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.HttpHeaders;
+import jakarta.inject.Inject;
+import jakarta.json.bind.Jsonb;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.ws.rs.HttpMethod;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.HttpHeaders;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
import org.talend.sdk.component.server.front.model.BulkRequests;
import org.talend.sdk.component.server.front.model.BulkResponses;
import org.talend.sdk.component.server.service.qualifier.ComponentServer;
import org.talend.sdk.component.server.test.ComponentClient;
-@MonoMeecrowaveConfig
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
class BulkReadResourceImplTest {
@Inject
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/ComponentResourceImplTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/ComponentResourceImplTest.java
index 3989cd76d5bac..ab722214f4ba8 100644
--- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/ComponentResourceImplTest.java
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/ComponentResourceImplTest.java
@@ -15,11 +15,11 @@
*/
package org.talend.sdk.component.server.front;
+import static jakarta.ws.rs.client.Entity.entity;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM_TYPE;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_SVG_XML_TYPE;
import static java.util.Collections.singletonList;
-import static javax.ws.rs.client.Entity.entity;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
-import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM_TYPE;
-import static javax.ws.rs.core.MediaType.APPLICATION_SVG_XML_TYPE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
@@ -51,18 +51,19 @@
import java.util.jar.JarFile;
import java.util.stream.IntStream;
-import javax.inject.Inject;
-import javax.ws.rs.NotFoundException;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.GenericType;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.NotFoundException;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.GenericType;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.apache.ziplock.IO;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.io.TempDir;
import org.talend.sdk.component.runtime.manager.extension.ComponentSchemaEnricher;
import org.talend.sdk.component.runtime.output.Branches;
@@ -80,7 +81,8 @@
import org.talend.sdk.component.server.test.ComponentClient;
import org.talend.sdk.component.server.test.websocket.WebsocketClient;
-@MonoMeecrowaveConfig
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
class ComponentResourceImplTest {
@Inject
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/ConfigurationTypeResourceImplTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/ConfigurationTypeResourceImplTest.java
index a2575d0b2cfba..3c9693ca1ef4a 100644
--- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/ConfigurationTypeResourceImplTest.java
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/ConfigurationTypeResourceImplTest.java
@@ -15,9 +15,9 @@
*/
package org.talend.sdk.component.server.front;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singleton;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -27,24 +27,26 @@
import java.util.stream.Collectors;
import java.util.stream.IntStream;
-import javax.inject.Inject;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonObject;
-import javax.json.spi.JsonProvider;
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.client.WebTarget;
+import jakarta.inject.Inject;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
+import jakarta.json.spi.JsonProvider;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.WebTarget;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
import org.talend.sdk.component.server.front.model.ConfigTypeNode;
import org.talend.sdk.component.server.front.model.ConfigTypeNodes;
import org.talend.sdk.component.server.front.model.ErrorDictionary;
import org.talend.sdk.component.server.front.model.error.ErrorPayload;
import org.talend.sdk.component.server.test.websocket.WebsocketClient;
-@MonoMeecrowaveConfig
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
class ConfigurationTypeResourceImplTest {
@Inject
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/DocumentationResourceImplTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/DocumentationResourceImplTest.java
index 9ac18db9cfc59..6194ef9cd791e 100644
--- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/DocumentationResourceImplTest.java
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/DocumentationResourceImplTest.java
@@ -15,24 +15,26 @@
*/
package org.talend.sdk.component.server.front;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.function.Function;
-import javax.inject.Inject;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.Response;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Response;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.junit.jupiter.api.RepeatedTest;
+import org.junit.jupiter.api.TestInstance;
import org.talend.sdk.component.server.front.model.DocumentationContent;
import org.talend.sdk.component.server.front.model.ErrorDictionary;
import org.talend.sdk.component.server.front.model.error.ErrorPayload;
import org.talend.sdk.component.server.test.ComponentClient;
import org.talend.sdk.component.server.test.websocket.WebsocketClient;
-@MonoMeecrowaveConfig
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
class DocumentationResourceImplTest {
@Inject
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/EntryTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/EntryTest.java
index 94e9397da01f0..089f85b23cedc 100644
--- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/EntryTest.java
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/EntryTest.java
@@ -23,8 +23,8 @@
import java.util.LinkedHashMap;
import java.util.Map;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
import org.junit.jupiter.api.Test;
import org.talend.sdk.component.api.record.SchemaProperty;
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/EnvironmentResourceImplTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/EnvironmentResourceImplTest.java
index eee5385c686a8..5bb6df9e9f687 100644
--- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/EnvironmentResourceImplTest.java
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/EnvironmentResourceImplTest.java
@@ -15,7 +15,7 @@
*/
package org.talend.sdk.component.server.front;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -23,16 +23,18 @@
import java.util.Date;
import java.util.stream.Stream;
-import javax.inject.Inject;
-import javax.ws.rs.client.WebTarget;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.client.WebTarget;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
import org.talend.sdk.component.server.front.model.Connectors;
import org.talend.sdk.component.server.front.model.Environment;
-@MonoMeecrowaveConfig
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
class EnvironmentResourceImplTest {
@Inject
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/MigrationTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/MigrationTest.java
index 091f1b8b25c7f..224712e99caa9 100644
--- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/MigrationTest.java
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/MigrationTest.java
@@ -15,25 +15,27 @@
*/
package org.talend.sdk.component.server.front;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.HashMap;
import java.util.Map;
-import javax.inject.Inject;
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.client.WebTarget;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.WebTarget;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
import org.talend.sdk.component.server.front.model.ConfigTypeNodes;
import org.talend.sdk.component.server.test.ComponentClient;
import org.talend.sdk.component.server.test.migration.MigrationDataSet;
import org.talend.sdk.component.server.test.migration.MigrationDataStore;
import org.talend.sdk.component.server.test.migration.MigrationInput;
-@MonoMeecrowaveConfig
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
class MigrationTest {
@Inject
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/SchemaTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/SchemaTest.java
index ca736d8d54bc8..8bdaf179274b6 100644
--- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/SchemaTest.java
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/SchemaTest.java
@@ -27,8 +27,8 @@
import java.io.StringReader;
import java.util.List;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/beam/BeamActionSerializationTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/beam/BeamActionSerializationTest.java
index aca38045c874a..617b680dcf449 100644
--- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/beam/BeamActionSerializationTest.java
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/beam/BeamActionSerializationTest.java
@@ -15,18 +15,24 @@
*/
package org.talend.sdk.component.server.front.beam;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static java.util.Collections.emptyMap;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import javax.inject.Inject;
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.client.WebTarget;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.WebTarget;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
-@MonoMeecrowaveConfig
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+// jsonbPrettify=true restores what InitTestInfra's Meecrowave.ConfigurationCustomizer already sets: any
+// @MeecrowaveConfig-annotated test unconditionally re-applies every annotation attribute - including
+// jsonbPrettify's own "false" default - onto the builder via reflection, silently overriding the
+// customizer once a test stops using @MonoMeecrowaveConfig (which never applies annotation attributes at all).
+@MeecrowaveConfig(scanningExcludes = "smallrye-config", jsonbPrettify = true)
class BeamActionSerializationTest {
@Inject
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/beam/BeamComponentResourceImplTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/beam/BeamComponentResourceImplTest.java
index cccd859100251..ed63b05286f3a 100644
--- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/beam/BeamComponentResourceImplTest.java
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/beam/BeamComponentResourceImplTest.java
@@ -15,20 +15,22 @@
*/
package org.talend.sdk.component.server.front.beam;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
-import javax.inject.Inject;
-import javax.ws.rs.client.WebTarget;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.client.WebTarget;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
import org.talend.sdk.component.server.front.model.Dependencies;
import org.talend.sdk.component.server.front.model.DependencyDefinition;
import org.talend.sdk.component.server.test.ComponentClient;
-@MonoMeecrowaveConfig
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
class BeamComponentResourceImplTest {
@Inject
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/memory/InMemoryRequestTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/memory/InMemoryRequestTest.java
new file mode 100644
index 0000000000000..2f57fb74e056c
--- /dev/null
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/memory/InMemoryRequestTest.java
@@ -0,0 +1,197 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.server.front.memory;
+
+import static java.util.Collections.list;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import jakarta.servlet.RequestDispatcher;
+import jakarta.servlet.ServletContext;
+
+import org.junit.jupiter.api.Test;
+import org.talend.sdk.component.server.front.security.ConnectionSecurityProvider;
+
+class InMemoryRequestTest {
+
+ private InMemoryRequest request(final Map> headers, final Principal principal,
+ final ServletContext context, final byte[] body) {
+ return new InMemoryRequest("GET", headers, "/api/v1/x", "/x", "/api", "a=b", 8080, context,
+ new MemoryInputStream(body == null ? null : new ByteArrayInputStream(body)), () -> principal, null);
+ }
+
+ @Test
+ void basics() {
+ final ServletContext context = mock(ServletContext.class);
+ when(context.getContextPath()).thenReturn("/ctx");
+ when(context.getVirtualServerName()).thenReturn("vserver");
+ final RequestDispatcher dispatcher = mock(RequestDispatcher.class);
+ when(context.getRequestDispatcher("/p")).thenReturn(dispatcher);
+ final Principal principal = () -> "bob";
+ final InMemoryRequest request = request(new HashMap<>(), principal, context, null);
+
+ assertEquals("GET", request.getMethod());
+ assertEquals("/x", request.getPathInfo());
+ assertEquals("/x", request.getPathTranslated());
+ assertEquals("/ctx", request.getContextPath());
+ assertEquals("a=b", request.getQueryString());
+ assertEquals("bob", request.getRemoteUser());
+ assertEquals(principal, request.getUserPrincipal());
+ assertEquals("/api/v1/x", request.getRequestURI());
+ assertEquals("/api/v1/x", request.getRequestURL().toString());
+ assertEquals("/api", request.getServletPath());
+ assertEquals("HTTP/1.1", request.getProtocol());
+ assertEquals("http", request.getScheme());
+ assertEquals("vserver", request.getServerName());
+ assertEquals(8080, request.getServerPort());
+ assertSame(context, request.getServletContext());
+ assertSame(dispatcher, request.getRequestDispatcher("/p"));
+ }
+
+ @Test
+ void sessionAndSecurityDefaults() {
+ final InMemoryRequest request = request(new HashMap<>(), null, mock(ServletContext.class), null);
+ assertNull(request.getAuthType());
+ assertEquals(0, request.getCookies().length);
+ assertNull(request.getRequestedSessionId());
+ assertNull(request.getSession());
+ assertNull(request.getSession(true));
+ assertNull(request.changeSessionId());
+ assertFalse(request.isRequestedSessionIdValid());
+ assertFalse(request.isRequestedSessionIdFromCookie());
+ assertFalse(request.isRequestedSessionIdFromURL());
+ assertFalse(request.authenticate(null));
+ assertFalse(request.isUserInRole("any"));
+ request.login("u", "p");
+ request.logout();
+ assertTrue(request.getParts().isEmpty());
+ assertNull(request.getPart("p"));
+ assertNull(request.upgrade(null));
+ }
+
+ @Test
+ void connectionAndAsyncDefaults() {
+ final InMemoryRequest request = request(new HashMap<>(), null, mock(ServletContext.class), null);
+ assertNull(request.getRemoteAddr());
+ assertNull(request.getRemoteHost());
+ assertEquals(0, request.getRemotePort());
+ assertNull(request.getLocalName());
+ assertNull(request.getLocalAddr());
+ assertEquals(0, request.getLocalPort());
+ assertFalse(request.isSecure());
+ assertNull(request.getServletConnection());
+ assertNotNull(request.getRequestId());
+ assertEquals("", request.getProtocolRequestId());
+ assertTrue(request.isAsyncSupported());
+ assertFalse(request.isAsyncStarted());
+ assertNull(request.getAsyncContext());
+ assertThrows(UnsupportedOperationException.class, request::getDispatcherType);
+ }
+
+ @Test
+ void noPrincipal() {
+ assertNull(request(new HashMap<>(), null, mock(ServletContext.class), null).getRemoteUser());
+ }
+
+ @Test
+ void headers() {
+ final Map> headers = new HashMap<>();
+ headers.put("h", List.of("v1", "v2"));
+ headers.put("i", List.of("12"));
+ headers.put("empty", List.of());
+ headers.put("d", List.of("Thu, 01 Jan 1970 00:00:01 GMT"));
+ headers.put("bad", List.of("not a date"));
+ final InMemoryRequest request = request(headers, null, mock(ServletContext.class), null);
+
+ assertEquals("v1", request.getHeader("h"));
+ assertNull(request.getHeader("missing"));
+ assertNull(request.getHeader("empty"));
+ assertEquals(List.of("v1", "v2"), list(request.getHeaders("h")));
+ assertNull(request.getHeaders("missing"));
+ assertNull(request.getHeaders("empty"));
+ assertEquals(4 + 1, list(request.getHeaderNames()).size());
+ assertEquals(12, request.getIntHeader("i"));
+ assertEquals(-1, request.getIntHeader("missing"));
+ assertEquals(-1L, request.getDateHeader("missing"));
+ assertEquals(1000L, request.getDateHeader("d"));
+ assertThrows(IllegalArgumentException.class, () -> request.getDateHeader("bad"));
+ }
+
+ @Test
+ void attributesAndEncoding() {
+ final InMemoryRequest request = request(new HashMap<>(), null, mock(ServletContext.class), null);
+ assertEquals(Boolean.TRUE, request.getAttribute(ConnectionSecurityProvider.SKIP));
+ assertNull(request.getAttribute("a"));
+ request.setAttribute("a", "b");
+ assertEquals("b", request.getAttribute("a"));
+ assertEquals(List.of("a"), list(request.getAttributeNames()));
+ request.removeAttribute("a");
+ assertNull(request.getAttribute("a"));
+
+ assertNull(request.getCharacterEncoding());
+ request.setCharacterEncoding("UTF-8");
+ assertEquals("UTF-8", request.getCharacterEncoding());
+ assertEquals(0, request.getContentLength());
+ assertEquals(0L, request.getContentLengthLong());
+ assertNull(request.getContentType());
+ }
+
+ @Test
+ void parametersAndLocale() {
+ final InMemoryRequest request = request(new HashMap<>(), null, mock(ServletContext.class), null);
+ assertNull(request.getParameter("p"));
+ assertNull(request.getParameterValues("p"));
+ assertFalse(request.getParameterNames().hasMoreElements());
+ request.getParameterMap().put("p", new String[] { "1", "2" });
+ request.getParameterMap().put("e", new String[0]);
+ assertEquals("1", request.getParameter("p"));
+ assertNull(request.getParameter("e"));
+ assertArrayEquals(new String[] { "1", "2" }, request.getParameterValues("p"));
+ assertEquals(2, list(request.getParameterNames()).size());
+ assertEquals(Locale.getDefault(), request.getLocale());
+ assertEquals(List.of(Locale.getDefault()), list(request.getLocales()));
+ }
+
+ @Test
+ void body() throws IOException {
+ final InMemoryRequest request = request(new HashMap<>(), null, mock(ServletContext.class),
+ "hello".getBytes(StandardCharsets.UTF_8));
+ assertNotNull(request.getInputStream());
+ final java.io.BufferedReader reader = request.getReader();
+ assertSame(reader, request.getReader());
+ assertEquals("hello", reader.readLine());
+
+ final InMemoryRequest empty = request(new HashMap<>(), null, mock(ServletContext.class), null);
+ assertEquals(-1, empty.getInputStream().read());
+ }
+}
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/memory/InMemoryResponseTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/memory/InMemoryResponseTest.java
new file mode 100644
index 0000000000000..a41e19c0a9d8f
--- /dev/null
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/front/memory/InMemoryResponseTest.java
@@ -0,0 +1,196 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.server.front.memory;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.servlet.ServletOutputStream;
+import jakarta.servlet.http.Cookie;
+import jakarta.servlet.http.HttpServletResponse;
+
+import org.junit.jupiter.api.Test;
+
+class InMemoryResponseTest {
+
+ private final List written = new ArrayList<>();
+
+ private final AtomicInteger flushes = new AtomicInteger();
+
+ private boolean open = true;
+
+ private InMemoryResponse response(final String preWrite) {
+ return new InMemoryResponse(() -> open, flushes::incrementAndGet, written::add, (status, headers) -> preWrite);
+ }
+
+ private String all() {
+ final StringBuilder out = new StringBuilder();
+ written.forEach(b -> out.append(new String(b, StandardCharsets.UTF_8)));
+ return out.toString();
+ }
+
+ @Test
+ void headers() {
+ final InMemoryResponse response = response("");
+ assertNull(response.getHeader("x"));
+ assertFalse(response.containsHeader("x"));
+ response.setHeader("X", "1");
+ assertTrue(response.containsHeader("x"));
+ response.addHeader("x", "2");
+ response.addHeader("y", "3");
+ assertEquals("1", response.getHeader("x"));
+ assertEquals(List.of("1", "2"), response.getHeaders("X"));
+ assertEquals("3", response.getHeader("y"));
+ response.setIntHeader("i", 4);
+ response.addIntHeader("j", 5);
+ response.setDateHeader("d", 6L);
+ response.addDateHeader("e", 7L);
+ assertEquals("4", response.getHeader("i"));
+ assertEquals("5", response.getHeader("j"));
+ assertEquals("6", response.getHeader("d"));
+ assertEquals("7", response.getHeader("e"));
+ response.addCookie(new Cookie("c", "v"));
+ assertEquals("v", response.getHeader("c"));
+ assertEquals(7, response.getHeaderNames().size());
+ response.setContentType("text/plain");
+ assertEquals("text/plain", response.getContentType());
+ }
+
+ @Test
+ void statusAndMisc() throws IOException {
+ final InMemoryResponse response = response("");
+ assertEquals(HttpServletResponse.SC_OK, response.getStatus());
+ assertFalse(response.isCommitted());
+ response.setStatus(201);
+ assertEquals(201, response.getCode());
+ assertTrue(response.isCommitted());
+ response.sendError(500);
+ assertEquals(500, response.getStatus());
+ response.sendError(404, "nope");
+ assertEquals(404, response.getStatus());
+ assertEquals("a", response.encodeURL("a"));
+ assertEquals("b", response.encodeRedirectURL("b"));
+ assertEquals("UTF-8", response.getCharacterEncoding());
+ response.setCharacterEncoding("ISO-8859-1");
+ assertEquals("ISO-8859-1", response.getCharacterEncoding());
+ response.setLocale(Locale.FRANCE);
+ assertEquals(Locale.FRANCE, response.getLocale());
+ response.setBufferSize(1);
+ response.setContentLength(1);
+ response.setContentLengthLong(1);
+ }
+
+ @Test
+ void redirect() throws IOException {
+ final InMemoryResponse response = response("");
+ response.getOutputStream().write('x');
+ response.sendRedirect("/there");
+ assertEquals(HttpServletResponse.SC_FOUND, response.getStatus());
+ assertEquals("/there", response.getHeader("Location"));
+ assertEquals(0, response.getBufferSize());
+ assertThrows(IllegalStateException.class, () -> response.sendRedirect("/again"));
+ }
+
+ @Test
+ void redirectWithoutClearingBuffer() throws IOException {
+ final InMemoryResponse response = response("");
+ response.getOutputStream();
+ response.sendRedirect("/there", 301, false);
+ assertEquals(301, response.getStatus());
+ }
+
+ @Test
+ void writeAndClose() throws IOException {
+ final InMemoryResponse response = response("HEAD\n");
+ final ServletOutputStream out = response.getOutputStream();
+ assertSame(out, response.getOutputStream());
+ assertTrue(out.isReady());
+ out.setWriteListener(null);
+ out.write("ab".getBytes(StandardCharsets.UTF_8), 0, 2);
+ out.write('c');
+ assertEquals(3, response.getBufferSize());
+ out.flush(); // below buffer size, nothing written yet
+ assertTrue(written.isEmpty());
+ out.close();
+ out.close();
+ assertEquals("HEAD\nabc", all());
+ assertEquals(1, flushes.get());
+ }
+
+ @Test
+ void writerAndEmptyHeader() throws IOException {
+ final InMemoryResponse response = response("");
+ response.getWriter().print("hi");
+ assertSame(response.getWriter(), response.getWriter());
+ response.flushBuffer();
+ response.getOutputStream().close();
+ assertEquals("hi", all());
+ }
+
+ @Test
+ void flushBufferWithoutWriter() {
+ assertDoesNotThrow(() -> response("").flushBuffer());
+ assertTrue(written.isEmpty());
+ }
+
+ @Test
+ void closeWithoutDataStillFlushes() throws IOException {
+ final InMemoryResponse response = response("");
+ response.getOutputStream().close();
+ assertTrue(written.isEmpty());
+ assertEquals(1, flushes.get());
+ }
+
+ @Test
+ void flushWhenClosedConnectionIsIgnored() throws IOException {
+ open = false;
+ final InMemoryResponse response = response("");
+ final ServletOutputStream out = response.getOutputStream();
+ out.write(new byte[9000], 0, 9000);
+ out.flush();
+ assertTrue(written.isEmpty());
+ }
+
+ @Test
+ void bigFlushWritesData() throws IOException {
+ final InMemoryResponse response = response("H");
+ final ServletOutputStream out = response.getOutputStream();
+ out.write(new byte[9000], 0, 9000);
+ out.flush();
+ assertEquals(2, written.size());
+ assertEquals(9001, written.stream().mapToInt(b -> b.length).sum());
+ }
+
+ @Test
+ void reset() throws IOException {
+ final InMemoryResponse response = response("");
+ response.getOutputStream().write('a');
+ response.reset();
+ assertEquals(0, response.getBufferSize());
+ }
+}
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/ActionDisplayNameTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/ActionDisplayNameTest.java
index 5db1b64f13f66..e6e70335df828 100644
--- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/ActionDisplayNameTest.java
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/ActionDisplayNameTest.java
@@ -19,14 +19,16 @@
import java.util.Locale;
-import javax.inject.Inject;
+import jakarta.inject.Inject;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
import org.talend.sdk.component.container.Container;
import org.talend.sdk.component.runtime.manager.ContainerComponentRegistry;
-@MonoMeecrowaveConfig
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
class ActionDisplayNameTest {
@Inject
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/ComponentManagerServiceTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/ComponentManagerServiceTest.java
index d94154dd2a0b9..2918eea631efd 100644
--- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/ComponentManagerServiceTest.java
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/ComponentManagerServiceTest.java
@@ -31,12 +31,13 @@
import java.util.Set;
import java.util.stream.Stream;
-import javax.inject.Inject;
+import jakarta.inject.Inject;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestMethodOrder;
import org.talend.sdk.component.container.Container;
import org.talend.sdk.component.runtime.manager.ComponentFamilyMeta;
@@ -47,7 +48,8 @@
import org.talend.sdk.component.server.dao.ComponentDao;
import org.talend.sdk.component.server.dao.ComponentFamilyDao;
-@MonoMeecrowaveConfig
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class ComponentManagerServiceTest {
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/IconResolverTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/IconResolverTest.java
index 4e213543fc3b7..d53b764f25fda 100644
--- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/IconResolverTest.java
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/IconResolverTest.java
@@ -22,16 +22,18 @@
import static org.talend.sdk.component.server.front.ComponentResourceImpl.THEME_DARK;
import static org.talend.sdk.component.server.front.ComponentResourceImpl.THEME_LIGHT;
-import javax.inject.Inject;
+import jakarta.inject.Inject;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
import org.talend.sdk.component.container.Container;
import org.talend.sdk.component.runtime.manager.ComponentManager;
-@MonoMeecrowaveConfig
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
class IconResolverTest {
public static final String PLUGIN_DB_INPUT = "db-input";
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/LocaleMapperTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/LocaleMapperTest.java
index 6760dfa33ed7c..5e6ef7406799e 100644
--- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/LocaleMapperTest.java
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/LocaleMapperTest.java
@@ -19,12 +19,14 @@
import java.util.Locale;
-import javax.inject.Inject;
+import jakarta.inject.Inject;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
-@MonoMeecrowaveConfig
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
class LocaleMapperTest {
@Inject
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/PropertiesServiceTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/PropertiesServiceTest.java
index e99a1c606b86a..48ac4d7569933 100644
--- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/PropertiesServiceTest.java
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/PropertiesServiceTest.java
@@ -31,11 +31,12 @@
import java.util.Map;
import java.util.Objects;
-import javax.inject.Inject;
+import jakarta.inject.Inject;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.apache.xbean.propertyeditor.PropertyEditorRegistry;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.configuration.ui.layout.GridLayout;
import org.talend.sdk.component.runtime.manager.ParameterMeta;
@@ -46,7 +47,8 @@
import lombok.Data;
-@MonoMeecrowaveConfig
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
class PropertiesServiceTest {
@Inject
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/UiSchemaTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/UiSchemaTest.java
index a0ae1b801dfa0..02d58b33db27c 100644
--- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/UiSchemaTest.java
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/UiSchemaTest.java
@@ -15,8 +15,8 @@
*/
package org.talend.sdk.component.server.service;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static java.util.Collections.emptyList;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -30,11 +30,12 @@
import java.util.function.Predicate;
import java.util.stream.Stream;
-import javax.inject.Inject;
-import javax.ws.rs.client.WebTarget;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.client.WebTarget;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
import org.talend.sdk.component.form.api.Client;
import org.talend.sdk.component.form.api.UiSpecService;
import org.talend.sdk.component.form.internal.converter.PropertyContext;
@@ -46,7 +47,8 @@
import org.talend.sdk.component.server.front.model.ConfigTypeNodes;
import org.talend.sdk.component.server.test.ComponentClient;
-@MonoMeecrowaveConfig
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
public class UiSchemaTest {
@Inject
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/VirtualDependenciesServiceTemplatingTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/VirtualDependenciesServiceTemplatingTest.java
index c53a70cce6e37..7100ad523d3bf 100644
--- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/VirtualDependenciesServiceTemplatingTest.java
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/VirtualDependenciesServiceTemplatingTest.java
@@ -20,7 +20,8 @@
import java.util.stream.Stream;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
+import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.talend.sdk.component.dependencies.maven.Artifact;
@@ -29,7 +30,8 @@
import lombok.RequiredArgsConstructor;
import lombok.ToString;
-@MonoMeecrowaveConfig
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
class VirtualDependenciesServiceTemplatingTest {
@ParameterizedTest
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/VirtualDependenciesServiceTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/VirtualDependenciesServiceTest.java
index a3b61b2c28781..9452a62992b8a 100644
--- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/VirtualDependenciesServiceTest.java
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/VirtualDependenciesServiceTest.java
@@ -15,11 +15,11 @@
*/
package org.talend.sdk.component.server.service;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM_TYPE;
import static java.util.Collections.emptyMap;
import static java.util.stream.Collectors.toMap;
import static java.util.stream.Collectors.toSet;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
-import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM_TYPE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
@@ -37,22 +37,24 @@
import java.util.stream.IntStream;
import java.util.stream.Stream;
-import javax.inject.Inject;
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.Response;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Response;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.apache.ziplock.IO;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.io.TempDir;
import org.talend.sdk.component.api.service.completion.SuggestionValues;
import org.talend.sdk.component.server.front.model.Dependencies;
import org.talend.sdk.component.server.front.model.DependencyDefinition;
import org.talend.sdk.component.server.test.ComponentClient;
-@MonoMeecrowaveConfig
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
class VirtualDependenciesServiceTest {
@Inject
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/FrontCacheKeyGeneratorTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/FrontCacheKeyGeneratorTest.java
new file mode 100644
index 0000000000000..830ac945188b9
--- /dev/null
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/FrontCacheKeyGeneratorTest.java
@@ -0,0 +1,96 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.server.service.jcache;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Field;
+import java.util.Locale;
+
+import javax.cache.annotation.CacheInvocationParameter;
+import javax.cache.annotation.CacheKeyInvocationContext;
+import javax.cache.annotation.GeneratedCacheKey;
+
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.MultivaluedHashMap;
+import jakarta.ws.rs.core.Request;
+import jakarta.ws.rs.core.UriInfo;
+
+import org.junit.jupiter.api.Test;
+
+class FrontCacheKeyGeneratorTest {
+
+ private FrontCacheKeyGenerator generator(final String path, final boolean failing) throws Exception {
+ final FrontCacheKeyGenerator generator = new FrontCacheKeyGenerator();
+ final UriInfo uriInfo = mock(UriInfo.class);
+ final HttpHeaders headers = mock(HttpHeaders.class);
+ if (failing) {
+ when(uriInfo.getPath()).thenThrow(new IllegalStateException("no request"));
+ } else {
+ when(uriInfo.getPath()).thenReturn(path);
+ when(uriInfo.getQueryParameters()).thenReturn(new MultivaluedHashMap<>());
+ when(headers.getLanguage()).thenReturn(Locale.ENGLISH);
+ when(headers.getHeaderString(HttpHeaders.ACCEPT)).thenReturn("application/json");
+ }
+ set(generator, "request", mock(Request.class));
+ set(generator, "uriInfo", uriInfo);
+ set(generator, "headers", headers);
+ return generator;
+ }
+
+ private static void set(final Object instance, final String name, final Object value) throws Exception {
+ final Field field = FrontCacheKeyGenerator.class.getDeclaredField(name);
+ field.setAccessible(true);
+ field.set(instance, value);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static CacheKeyInvocationContext context(final Object value) {
+ final CacheInvocationParameter parameter = mock(CacheInvocationParameter.class);
+ when(parameter.getValue()).thenReturn(value);
+ final CacheKeyInvocationContext context = mock(CacheKeyInvocationContext.class);
+ when(context.getKeyParameters()).thenReturn(new CacheInvocationParameter[] { parameter });
+ return context;
+ }
+
+ @Test
+ void equalContextsGiveEqualKeys() throws Exception {
+ final GeneratedCacheKey first = generator("/a", false).generateCacheKey(context("p"));
+ final GeneratedCacheKey second = generator("/a", false).generateCacheKey(context("p"));
+ assertEquals(first, second);
+ assertEquals(first.hashCode(), second.hashCode());
+ assertEquals(first, first);
+ }
+
+ @Test
+ void differentContextsGiveDifferentKeys() throws Exception {
+ final GeneratedCacheKey key = generator("/a", false).generateCacheKey(context("p"));
+ assertNotEquals(key, generator("/b", false).generateCacheKey(context("p")));
+ assertNotEquals(key, generator("/a", false).generateCacheKey(context("q")));
+ assertNotEquals(null, key);
+ }
+
+ @Test
+ void notApplicableContextFallsBackToParametersOnly() throws Exception {
+ final GeneratedCacheKey withContext = generator("/a", false).generateCacheKey(context("p"));
+ final GeneratedCacheKey without = generator("/a", true).generateCacheKey(context("p"));
+ assertNotEquals(withContext, without);
+ assertEquals(without, generator("/z", true).generateCacheKey(context("p")));
+ }
+}
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/FrontCacheResolverTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/FrontCacheResolverTest.java
index 69da08cf066f2..4c9b3796f722b 100644
--- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/FrontCacheResolverTest.java
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/FrontCacheResolverTest.java
@@ -15,21 +15,23 @@
*/
package org.talend.sdk.component.server.service.jcache;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import javax.inject.Inject;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.Response;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Response;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
import org.talend.sdk.component.server.front.model.CacheClear;
import org.talend.sdk.component.server.service.ComponentManagerService;
import org.talend.sdk.component.server.test.ComponentClient;
-@MonoMeecrowaveConfig
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
class FrontCacheResolverTest {
@Inject
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/cdi/CDIJCacheHelperTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/cdi/CDIJCacheHelperTest.java
new file mode 100644
index 0000000000000..8e125fb3f05e8
--- /dev/null
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/cdi/CDIJCacheHelperTest.java
@@ -0,0 +1,394 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.server.service.jcache.cdi;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.CompletionStage;
+
+import javax.cache.annotation.CacheDefaults;
+import javax.cache.annotation.CacheKey;
+import javax.cache.annotation.CacheKeyGenerator;
+import javax.cache.annotation.CachePut;
+import javax.cache.annotation.CacheRemoveAll;
+import javax.cache.annotation.CacheResolverFactory;
+import javax.cache.annotation.CacheResult;
+import javax.cache.annotation.CacheValue;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.context.RequestScoped;
+import jakarta.enterprise.context.spi.CreationalContext;
+import jakarta.enterprise.inject.spi.Bean;
+import jakarta.enterprise.inject.spi.BeanManager;
+import jakarta.interceptor.InvocationContext;
+
+import org.apache.geronimo.jcache.simple.cdi.CacheResolverFactoryImpl;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+class CDIJCacheHelperTest {
+
+ @Mock
+ private BeanManager beanManager;
+
+ private CDIJCacheHelper helper;
+
+ @BeforeEach
+ void setUp() throws Exception {
+ helper = new CDIJCacheHelper();
+ setField(helper, "beanManager", beanManager);
+ }
+
+ @Test
+ void findMetaCachesMethodMetaPerTargetTypeAndMethod() throws Exception {
+ final Target target = new Target();
+ final Method method = Target.class.getDeclaredMethod("load", String.class);
+ final InvocationContext ic = mockInvocationContext(method, target);
+
+ final CDIJCacheHelper.MethodMeta first = helper.findMeta(ic);
+ final CDIJCacheHelper.MethodMeta second = helper.findMeta(ic);
+
+ assertSame(first, second, "MethodMeta must be memoized for the same target type + method");
+ }
+
+ @Test
+ void findMetaResolvesCacheResultAnnotationAndKeyIndices() throws Exception {
+ final Target target = new Target();
+ final Method method = Target.class.getDeclaredMethod("load", String.class);
+ final InvocationContext ic = mockInvocationContext(method, target);
+
+ final CDIJCacheHelper.MethodMeta meta = helper.findMeta(ic);
+
+ assertEquals("resultCache", meta.getCacheResultCacheName());
+ assertNotNull(meta.getCacheResult());
+ assertArrayEquals(new Integer[] { 0 }, meta.getKeysIndices());
+ assertEquals(-1, meta.getValueIndex());
+ assertFalse(meta.isCompletionStage());
+ }
+
+ @Test
+ void findMetaDetectsCompletionStageReturnType() throws Exception {
+ final Target target = new Target();
+ final Method method = Target.class.getDeclaredMethod("loadAsync", String.class);
+ final InvocationContext ic = mockInvocationContext(method, target);
+
+ final CDIJCacheHelper.MethodMeta meta = helper.findMeta(ic);
+
+ assertTrue(meta.isCompletionStage());
+ }
+
+ @Test
+ void findMetaFixesValueParameterIndexForCachePutWithLeadingKeyParameter() throws Exception {
+ final Target target = new Target();
+ final Method method = Target.class.getDeclaredMethod("put", String.class, String.class);
+ final InvocationContext ic = mockInvocationContext(method, target);
+
+ final CDIJCacheHelper.MethodMeta meta = helper.findMeta(ic);
+
+ // regression test for QTDI-3358 round 2's "idx off-by-one" fix: the @CacheValue parameter is the
+ // *second* parameter (index 1), not the first.
+ assertEquals(1, meta.getValueIndex());
+ assertArrayEquals(new Integer[] { 0 }, meta.getKeysIndices());
+ assertTrue(meta.isCachePutAfter());
+ }
+
+ @Test
+ void findMetaUsesAllNonValueParametersAsKeysWhenNoneAreExplicitlyAnnotated() throws Exception {
+ final Target target = new Target();
+ final Method method = Target.class.getDeclaredMethod("putImplicitKeys", String.class, String.class);
+ final InvocationContext ic = mockInvocationContext(method, target);
+
+ final CDIJCacheHelper.MethodMeta meta = helper.findMeta(ic);
+
+ assertArrayEquals(new Integer[] { 0 }, meta.getKeysIndices());
+ assertEquals(1, meta.getValueIndex());
+ }
+
+ @Test
+ void findMetaFallsBackToClassLevelCacheDefaultsNameWhenAnnotationNameIsEmpty() throws Exception {
+ final DefaultedTarget target = new DefaultedTarget();
+ final Method method = DefaultedTarget.class.getDeclaredMethod("load", String.class);
+ final InvocationContext ic = mockInvocationContext(method, target);
+
+ final CDIJCacheHelper.MethodMeta meta = helper.findMeta(ic);
+
+ assertEquals("fallback-name", meta.getCacheResultCacheName());
+ }
+
+ @Test
+ void findMetaGeneratesNameFromMethodSignatureWhenNoNameIsAvailable() throws Exception {
+ final Target target = new Target();
+ final Method method = Target.class.getDeclaredMethod("removeAllNoName");
+ final InvocationContext ic = mockInvocationContext(method, target);
+
+ final CDIJCacheHelper.MethodMeta meta = helper.findMeta(ic);
+
+ assertEquals(Target.class.getName() + ".removeAllNoName()", meta.getCacheRemoveAllCacheName());
+ }
+
+ @Test
+ void findMetaResolvesCacheDefaultsThroughProxyInterface() throws Exception {
+ final ProxiedTarget proxy = (ProxiedTarget) Proxy
+ .newProxyInstance(getClass().getClassLoader(), new Class>[] { ProxiedTarget.class },
+ (InvocationHandler) (p, m, args) -> null);
+ final Method method = ProxiedTarget.class.getDeclaredMethod("load", String.class);
+ final InvocationContext ic = mockInvocationContext(method, proxy);
+
+ final CDIJCacheHelper.MethodMeta meta = helper.findMeta(ic);
+
+ assertEquals("proxy-fallback", meta.getCacheResultCacheName());
+ }
+
+ @Test
+ void isIncludedReturnsFalseWhenNoInOrOutClassesAreConfigured() {
+ assertFalse(helper.isIncluded(IllegalStateException.class, new Class>[0], new Class>[0]));
+ }
+
+ @Test
+ void isIncludedReturnsTrueWhenClassMatchesInAndNotOut() {
+ assertTrue(helper
+ .isIncluded(IllegalStateException.class, new Class>[] { RuntimeException.class },
+ new Class>[0]));
+ }
+
+ @Test
+ void isIncludedReturnsFalseWhenClassMatchesBothInAndOut() {
+ assertFalse(helper
+ .isIncluded(IllegalStateException.class, new Class>[] { RuntimeException.class },
+ new Class>[] { IllegalStateException.class }));
+ }
+
+ @Test
+ void isIncludedReturnsFalseWhenClassDoesNotMatchIn() {
+ assertFalse(helper
+ .isIncluded(IllegalArgumentException.class, new Class>[] { NullPointerException.class },
+ new Class>[0]));
+ }
+
+ @Test
+ void findMetaResolvesCustomCdiKeyGeneratorFromNormalScopedBean() throws Exception {
+ final CustomKeyGenerator generatorInstance = new CustomKeyGenerator();
+ mockBean(CustomKeyGenerator.class, generatorInstance, true);
+
+ final CustomGeneratorTarget target = new CustomGeneratorTarget();
+ final Method method = CustomGeneratorTarget.class.getDeclaredMethod("load", String.class);
+ final InvocationContext ic = mockInvocationContext(method, target);
+
+ final CDIJCacheHelper.MethodMeta meta = helper.findMeta(ic);
+
+ assertSame(generatorInstance, meta.getCacheResultKeyGenerator());
+ }
+
+ @Test
+ void findMetaResolvesCustomCdiResolverFactoryFromPseudoScopedBeanAndDefersRelease() throws Exception {
+ final CustomResolverFactory factoryInstance = new CustomResolverFactory();
+ final CreationalContext> context = mockBean(CustomResolverFactory.class, factoryInstance, false);
+
+ final CustomResolverTarget target = new CustomResolverTarget();
+ final Method method = CustomResolverTarget.class.getDeclaredMethod("load", String.class);
+ final InvocationContext ic = mockInvocationContext(method, target);
+
+ final CDIJCacheHelper.MethodMeta meta = helper.findMeta(ic);
+
+ assertSame(factoryInstance, meta.getCacheResultResolverFactory());
+ // pseudo-scoped beans are not released immediately - they are deferred to CDIJCacheHelper#release
+ verify(context, never()).release();
+
+ invokePrivate(helper, "release");
+ verify(context).release();
+ }
+
+ @Test
+ void releaseSwallowsRuntimeExceptionRaisedByCreationalContextRelease() throws Exception {
+ final CreationalContext> failingContext = mock(CreationalContext.class);
+ org.mockito.Mockito
+ .doThrow(new IllegalStateException("boom"))
+ .when(failingContext)
+ .release();
+ addToRelease(helper, failingContext);
+
+ // must not propagate - CDIJCacheHelper#release logs and continues releasing the remaining contexts
+ invokePrivate(helper, "release");
+ verify(failingContext).release();
+ }
+
+ @Test
+ void releaseClosesTheLazilyCreatedDefaultCacheResolverFactory() throws Exception {
+ final CacheResolverFactoryImpl mockFactory = mock(CacheResolverFactoryImpl.class);
+ setField(helper, "defaultCacheResolverFactory", mockFactory);
+
+ invokePrivate(helper, "release");
+
+ verify(mockFactory).release();
+ }
+
+ private InvocationContext mockInvocationContext(final Method method, final Object target) {
+ final InvocationContext ic = mock(InvocationContext.class);
+ when(ic.getMethod()).thenReturn(method);
+ when(ic.getTarget()).thenReturn(target);
+ return ic;
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private CreationalContext> mockBean(final Class type, final T instance, final boolean normalScope) {
+ final Bean bean = mock(Bean.class);
+ final Set> beans = new HashSet<>();
+ beans.add(bean);
+ final CreationalContext context = mock(CreationalContext.class);
+ when(beanManager.getBeans(type)).thenReturn(beans);
+ when(beanManager.resolve(beans)).thenReturn(bean);
+ when(beanManager.createCreationalContext(bean)).thenReturn(context);
+ when(bean.getScope()).thenReturn(normalScope ? ApplicationScoped.class : RequestScoped.class);
+ when(beanManager.isNormalScope(any())).thenReturn(normalScope);
+ when(bean.getBeanClass()).thenReturn((Class) type);
+ when(beanManager.getReference(bean, (Class) type, context)).thenReturn(instance);
+ return context;
+ }
+
+ private static void setField(final Object target, final String name, final Object value) throws Exception {
+ final Field field = target.getClass().getDeclaredField(name);
+ field.setAccessible(true);
+ field.set(target, value);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static void addToRelease(final CDIJCacheHelper target, final CreationalContext> context)
+ throws Exception {
+ final Field field = CDIJCacheHelper.class.getDeclaredField("toRelease");
+ field.setAccessible(true);
+ ((java.util.Collection>) field.get(target)).add(context);
+ }
+
+ private static void invokePrivate(final Object target, final String name) throws Exception {
+ final Method method = target.getClass().getDeclaredMethod(name);
+ method.setAccessible(true);
+ try {
+ method.invoke(target);
+ } catch (final java.lang.reflect.InvocationTargetException e) {
+ if (e.getCause() instanceof RuntimeException) {
+ throw (RuntimeException) e.getCause();
+ }
+ throw e;
+ }
+ }
+
+ private static class Target {
+
+ @CacheResult(cacheName = "resultCache")
+ String load(@CacheKey final String id) {
+ return null;
+ }
+
+ @CacheResult(cacheName = "asyncCache")
+ CompletionStage loadAsync(@CacheKey final String id) {
+ return null;
+ }
+
+ @CachePut
+ void put(@CacheKey final String id, @CacheValue final String value) {
+ // no-op, only annotation metadata matters for these tests
+ }
+
+ @CachePut
+ void putImplicitKeys(final String id, @CacheValue final String value) {
+ // no-op - id has no explicit @CacheKey, it must still be inferred as a key parameter
+ }
+
+ @CacheRemoveAll
+ void removeAllNoName() {
+ // no-op
+ }
+ }
+
+ @CacheDefaults(cacheName = "fallback-name")
+ private static class DefaultedTarget {
+
+ @CacheResult
+ String load(@CacheKey final String id) {
+ return null;
+ }
+ }
+
+ @CacheDefaults(cacheName = "proxy-fallback")
+ private interface ProxiedTarget {
+
+ @CacheResult
+ String load(@CacheKey final String id);
+ }
+
+ private static class CustomKeyGenerator implements CacheKeyGenerator {
+
+ @Override
+ public javax.cache.annotation.GeneratedCacheKey generateCacheKey(
+ final javax.cache.annotation.CacheKeyInvocationContext extends java.lang.annotation.Annotation> context) {
+ return null;
+ }
+ }
+
+ private static class CustomGeneratorTarget {
+
+ @CacheResult(cacheName = "customGenCache", cacheKeyGenerator = CustomKeyGenerator.class)
+ String load(@CacheKey final String id) {
+ return null;
+ }
+ }
+
+ private static class CustomResolverFactory implements CacheResolverFactory {
+
+ @Override
+ public javax.cache.annotation.CacheResolver getCacheResolver(
+ final javax.cache.annotation.CacheMethodDetails extends java.lang.annotation.Annotation> details) {
+ return null;
+ }
+
+ @Override
+ public javax.cache.annotation.CacheResolver getExceptionCacheResolver(
+ final javax.cache.annotation.CacheMethodDetails details) {
+ return null;
+ }
+ }
+
+ private static class CustomResolverTarget {
+
+ @CacheResult(cacheName = "customResolverCache", cacheResolverFactory = CustomResolverFactory.class)
+ String load(@CacheKey final String id) {
+ return null;
+ }
+ }
+}
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/cdi/CacheInvocationContextImplTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/cdi/CacheInvocationContextImplTest.java
new file mode 100644
index 0000000000000..6f0de1690b5c5
--- /dev/null
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/cdi/CacheInvocationContextImplTest.java
@@ -0,0 +1,130 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.server.service.jcache.cdi;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Method;
+
+import javax.cache.annotation.CacheInvocationParameter;
+import javax.cache.annotation.CacheKey;
+import javax.cache.annotation.CachePut;
+import javax.cache.annotation.CacheResult;
+import javax.cache.annotation.CacheValue;
+
+import jakarta.enterprise.inject.spi.BeanManager;
+import jakarta.interceptor.InvocationContext;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class CacheInvocationContextImplTest {
+
+ private CDIJCacheHelper helper;
+
+ private final Target target = new Target();
+
+ @BeforeEach
+ void setUp() throws Exception {
+ helper = new CDIJCacheHelper();
+ final java.lang.reflect.Field field = CDIJCacheHelper.class.getDeclaredField("beanManager");
+ field.setAccessible(true);
+ field.set(helper, mock(BeanManager.class));
+ }
+
+ private InvocationContext context(final String name, final Object[] params) throws Exception {
+ final Method method = Target.class.getDeclaredMethod(name, String.class, String.class);
+ final InvocationContext ic = mock(InvocationContext.class);
+ when(ic.getMethod()).thenReturn(method);
+ when(ic.getTarget()).thenReturn(target);
+ when(ic.getParameters()).thenReturn(params);
+ return ic;
+ }
+
+ @Test
+ void invocationContext() throws Exception {
+ final InvocationContext ic = context("put", new Object[] { "k", "v" });
+ final CachePut annotation = ic.getMethod().getAnnotation(CachePut.class);
+ final CacheInvocationContextImpl impl =
+ new CacheInvocationContextImpl<>(ic, annotation, "name", helper.findMeta(ic));
+
+ assertSame(target, impl.getTarget());
+ assertSame(ic.getMethod(), impl.getMethod());
+ assertSame(annotation, impl.getCacheAnnotation());
+ assertEquals("name", impl.getCacheName());
+ assertNotNull(impl.getAnnotations());
+ final CacheInvocationParameter[] all = impl.getAllParameters();
+ assertEquals(2, all.length);
+ assertEquals("k", all[0].getValue());
+ assertEquals("v", all[1].getValue());
+ assertEquals(1, all[1].getParameterPosition());
+ assertSame(all, impl.getAllParameters());
+ assertSame(impl, impl.unwrap(CacheInvocationContextImpl.class));
+ assertThrows(IllegalArgumentException.class, () -> impl.unwrap(String.class));
+ }
+
+ @Test
+ void nullParameters() throws Exception {
+ final InvocationContext ic = context("put", new Object[] { "k", "v" });
+ final CacheInvocationContextImpl impl = new CacheInvocationContextImpl<>(ic,
+ ic.getMethod().getAnnotation(CachePut.class), "name", helper.findMeta(ic));
+ when(ic.getParameters()).thenReturn(null);
+ assertEquals(0, impl.getAllParameters().length);
+ }
+
+ @Test
+ void keyAndValueParameters() throws Exception {
+ final InvocationContext ic = context("put", new Object[] { "k", "v" });
+ final CacheKeyInvocationContextImpl impl = new CacheKeyInvocationContextImpl<>(ic,
+ ic.getMethod().getAnnotation(CachePut.class), "name", helper.findMeta(ic));
+
+ final CacheInvocationParameter[] keys = impl.getKeyParameters();
+ assertEquals(1, keys.length);
+ assertEquals("k", keys[0].getValue());
+ assertSame(keys, impl.getKeyParameters());
+ final CacheInvocationParameter value = impl.getValueParameter();
+ assertEquals("v", value.getValue());
+ assertSame(value, impl.getValueParameter());
+ }
+
+ @Test
+ void noValueParameter() throws Exception {
+ final InvocationContext ic = context("result", new Object[] { "k", "v" });
+ final CacheKeyInvocationContextImpl impl = new CacheKeyInvocationContextImpl<>(ic,
+ ic.getMethod().getAnnotation(CacheResult.class), "name", helper.findMeta(ic));
+ assertNull(impl.getValueParameter());
+ assertEquals(2, impl.getKeyParameters().length);
+ }
+
+ private static class Target {
+
+ @CachePut(cacheName = "cic-put")
+ void put(@CacheKey final String id, @CacheValue final String value) {
+ // no-op
+ }
+
+ @CacheResult(cacheName = "cic-result")
+ String result(final String id, final String other) {
+ return id;
+ }
+ }
+}
diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/cdi/CachePutInterceptorTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/cdi/CachePutInterceptorTest.java
new file mode 100644
index 0000000000000..95a5f4374c166
--- /dev/null
+++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/cdi/CachePutInterceptorTest.java
@@ -0,0 +1,204 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.server.service.jcache.cdi;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.concurrent.CompletableFuture;
+
+import javax.cache.Cache;
+import javax.cache.Caching;
+import javax.cache.annotation.CacheInvocationParameter;
+import javax.cache.annotation.CacheKey;
+import javax.cache.annotation.CachePut;
+import javax.cache.annotation.CacheValue;
+
+import jakarta.enterprise.inject.spi.BeanManager;
+import jakarta.interceptor.InvocationContext;
+
+import org.apache.geronimo.jcache.simple.cdi.GeneratedCacheKeyImpl;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Exercises {@link CachePutInterceptor} against a real {@link CDIJCacheHelper} and the default
+ * (in-memory, geronimo-jcache-simple provided) JCache implementation - no live external system is
+ * involved, per java-testing-conventions.md.
+ */
+class CachePutInterceptorTest {
+
+ private CDIJCacheHelper helper;
+
+ private CachePutInterceptor interceptor;
+
+ private Target target;
+
+ @BeforeEach
+ void setUp() throws Exception {
+ helper = new CDIJCacheHelper();
+ final java.lang.reflect.Field field = CDIJCacheHelper.class.getDeclaredField("beanManager");
+ field.setAccessible(true);
+ field.set(helper, mock(BeanManager.class));
+ interceptor = new CachePutInterceptor(helper);
+ target = new Target();
+ }
+
+ @Test
+ void beforeInvocationPutsValueBeforeInvokingTheMethod() throws Throwable {
+ final Method method = Target.class.getDeclaredMethod("putBefore", String.class, String.class);
+ final InvocationContext ic = mockContext(method, "k1", "v1");
+ when(ic.proceed()).thenAnswer(invocation -> {
+ // the whole point of afterInvocation=false: the value must already be visible while the
+ // intercepted method itself is still executing.
+ assertEquals("v1", cachedValue("cpi-beforeCache", "k1"));
+ return null;
+ });
+
+ interceptor.cache(ic);
+
+ assertEquals("v1", cachedValue("cpi-beforeCache", "k1"));
+ }
+
+ @Test
+ void afterInvocationDoesNotPutBeforeTheMethodRunsButDoesAfterItSucceeds() throws Throwable {
+ final Method method = Target.class.getDeclaredMethod("putAfter", String.class, String.class);
+ final InvocationContext ic = mockContext(method, "k2", "v2");
+ when(ic.proceed()).thenAnswer(invocation -> {
+ assertNull(cachedValue("cpi-afterCache", "k2"), "afterInvocation=true must not put before proceed()");
+ return null;
+ });
+
+ interceptor.cache(ic);
+
+ assertEquals("v2", cachedValue("cpi-afterCache", "k2"));
+ }
+
+ @Test
+ void valueParameterUsesTheSecondParameterNotTheFirst() throws Throwable {
+ // regression test for QTDI-3358 round 2's "idx off-by-one" fix in
+ // CDIJCacheHelper.getValueParameter: the cached value must be "v3" (the @CacheValue
+ // parameter), never "k3" (the @CacheKey one).
+ final Method method = Target.class.getDeclaredMethod("putBefore", String.class, String.class);
+ final InvocationContext ic = mockContext(method, "k3", "v3");
+ when(ic.proceed()).thenReturn(null);
+
+ interceptor.cache(ic);
+
+ assertEquals("v3", cachedValue("cpi-beforeCache", "k3"));
+ }
+
+ @Test
+ void afterInvocationDoesNotPutWhenTheMethodThrowsAndExceptionIsNotIncluded() throws Throwable {
+ final Method method = Target.class.getDeclaredMethod("putAfterCacheForIllegalState", String.class,
+ String.class);
+ final InvocationContext ic = mockContext(method, "k4", "v4");
+ when(ic.proceed()).thenThrow(new IllegalArgumentException("not-included"));
+
+ assertThrows(IllegalArgumentException.class, () -> interceptor.cache(ic));
+ assertNull(cachedValue("cpi-afterCacheForCache", "k4"));
+ }
+
+ @Test
+ void afterInvocationPutsWhenTheMethodThrowsAnIncludedException() throws Throwable {
+ final Method method = Target.class.getDeclaredMethod("putAfterCacheForIllegalState", String.class,
+ String.class);
+ final InvocationContext ic = mockContext(method, "k5", "v5");
+ when(ic.proceed()).thenThrow(new IllegalStateException("included"));
+
+ assertThrows(IllegalStateException.class, () -> interceptor.cache(ic));
+ assertEquals("v5", cachedValue("cpi-afterCacheForCache", "k5"));
+ }
+
+ @Test
+ void synchronousCheckedExceptionPropagatesUnwrapped() throws Throwable {
+ final Method method = Target.class.getDeclaredMethod("putThrowsChecked", String.class, String.class);
+ final InvocationContext ic = mockContext(method, "k6", "v6");
+ final IOException checked = new IOException("checked-failure");
+ when(ic.proceed()).thenThrow(checked);
+
+ final Throwable thrown = assertThrows(IOException.class, () -> interceptor.cache(ic));
+ assertSame(checked, thrown);
+ }
+
+ @Test
+ void asyncFailureWrapsCheckedExceptionButDoesNotPropagateToTheCaller() throws Throwable {
+ final Method method = Target.class.getDeclaredMethod("putAsync", String.class, String.class);
+ final InvocationContext ic = mockContext(method, "k7", "v7");
+ final CompletableFuture future = new CompletableFuture<>();
+ when(ic.proceed()).thenReturn(future);
+
+ final Object result = interceptor.cache(ic);
+ assertSame(future, result);
+
+ // must not throw - CachePutInterceptor#onFailure wraps checked exceptions into
+ // IllegalStateException, but that is only observable on the *derived* stage, never on the
+ // original future returned to the caller of completeExceptionally().
+ future.completeExceptionally(new IOException("async-checked-failure"));
+ }
+
+ private static Object cachedValue(final String cacheName, final Object key) {
+ final Cache
- org.apache.geronimo.specs
- geronimo-jaxrs_2.1_spec
- ${geronimo-jaxrs.version}
+ jakarta.ws.rs
+ jakarta.ws.rs-api
- org.apache.geronimo.specs
- geronimo-jsonb_1.0_spec
- ${geronimo-jsonb.version}
+ jakarta.json.bind
+ jakarta.json.bind-api
org.apache.geronimo.specs
diff --git a/component-server-parent/extensions/component-server-extension-api/src/main/java/org/talend/sdk/component/server/extension/api/action/Action.java b/component-server-parent/extensions/component-server-extension-api/src/main/java/org/talend/sdk/component/server/extension/api/action/Action.java
index 7e06e7119b4e5..d7044aeadec0e 100644
--- a/component-server-parent/extensions/component-server-extension-api/src/main/java/org/talend/sdk/component/server/extension/api/action/Action.java
+++ b/component-server-parent/extensions/component-server-extension-api/src/main/java/org/talend/sdk/component/server/extension/api/action/Action.java
@@ -19,7 +19,7 @@
import java.util.concurrent.CompletionStage;
import java.util.function.BiFunction;
-import javax.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response;
import org.talend.sdk.component.server.front.model.ActionReference;
diff --git a/component-starter-server/pom.xml b/component-starter-server/pom.xml
index 493239f96b90f..8c988fe7ef1e0 100644
--- a/component-starter-server/pom.xml
+++ b/component-starter-server/pom.xml
@@ -36,9 +36,20 @@
-
+
org.apache.johnzon
johnzon-jsonb
+ ${johnzon.version}
+
+
+
+ org.apache.johnzon
+ johnzon-core
+ ${johnzon.version}
org.apache.meecrowave
@@ -79,8 +90,8 @@
microprofile-config-api
- org.apache.geronimo.config
- geronimo-config-impl
+ io.smallrye.config
+ smallrye-config
org.apache.logging.log4j
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/configuration/ComponentConfigurationLoader.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/configuration/ComponentConfigurationLoader.java
index 58df16714c093..b316df3a89fbb 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/configuration/ComponentConfigurationLoader.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/configuration/ComponentConfigurationLoader.java
@@ -28,8 +28,8 @@
import java.util.Properties;
import java.util.Set;
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.inject.spi.CDI;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.inject.spi.CDI;
import org.apache.meecrowave.Meecrowave;
import org.apache.meecrowave.runner.cli.CliOption;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/configuration/ScmConfigurationLoader.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/configuration/ScmConfigurationLoader.java
index 7d6bf4304b931..5c11cc371fb40 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/configuration/ScmConfigurationLoader.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/configuration/ScmConfigurationLoader.java
@@ -22,7 +22,7 @@
import java.util.Properties;
import java.util.Set;
-import javax.enterprise.inject.Vetoed;
+import jakarta.enterprise.inject.Vetoed;
import org.eclipse.microprofile.config.spi.ConfigSource;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/configuration/ServletConfigurer.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/configuration/ServletConfigurer.java
index 4d53287c582cf..890acafb650a2 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/configuration/ServletConfigurer.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/configuration/ServletConfigurer.java
@@ -19,17 +19,17 @@
import java.util.EnumSet;
import java.util.Set;
-import javax.inject.Inject;
-import javax.servlet.DispatcherType;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterRegistration;
-import javax.servlet.ServletContainerInitializer;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletResponse;
+import jakarta.inject.Inject;
+import jakarta.servlet.DispatcherType;
+import jakarta.servlet.Filter;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.FilterRegistration;
+import jakarta.servlet.ServletContainerInitializer;
+import jakarta.servlet.ServletContext;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.http.HttpServletResponse;
import org.apache.catalina.filters.HttpHeaderSecurityFilter;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/configuration/StarterConfiguration.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/configuration/StarterConfiguration.java
index f7c7e3c66c8e1..044e50e92b575 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/configuration/StarterConfiguration.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/configuration/StarterConfiguration.java
@@ -17,8 +17,8 @@
import java.util.Set;
-import javax.enterprise.context.ApplicationScoped;
-import javax.inject.Inject;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
import org.eclipse.microprofile.config.inject.ConfigProperty;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/ApiDemoEndpoints.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/ApiDemoEndpoints.java
index 22eee58850939..80f87b4d718df 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/ApiDemoEndpoints.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/ApiDemoEndpoints.java
@@ -15,27 +15,27 @@
*/
package org.talend.sdk.component.starter.server.front;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
-import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM;
-import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM_TYPE;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM_TYPE;
import java.io.IOException;
import java.io.InputStream;
import java.time.ZonedDateTime;
import java.util.Map;
-import javax.enterprise.context.ApplicationScoped;
-import javax.json.Json;
-import javax.json.JsonObject;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.Response;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
+import jakarta.ws.rs.DefaultValue;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.core.Response;
import lombok.extern.slf4j.Slf4j;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/EnvironmentResource.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/EnvironmentResource.java
index 799648ae6af57..2d17bdc88145c 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/EnvironmentResource.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/EnvironmentResource.java
@@ -15,10 +15,10 @@
*/
package org.talend.sdk.component.starter.server.front;
-import javax.enterprise.context.ApplicationScoped;
-import javax.inject.Inject;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
import org.talend.sdk.component.starter.server.model.Environment;
import org.talend.sdk.component.starter.server.service.info.ServerInfo;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/ProjectResource.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/ProjectResource.java
index f3bc9d74c2b46..9556be62f2533 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/ProjectResource.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/ProjectResource.java
@@ -15,13 +15,13 @@
*/
package org.talend.sdk.component.starter.server.front;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonList;
import static java.util.Optional.ofNullable;
import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toMap;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -39,23 +39,23 @@
import java.util.TreeMap;
import java.util.stream.Stream;
-import javax.annotation.PostConstruct;
-import javax.enterprise.context.ApplicationScoped;
-import javax.inject.Inject;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.FormParam;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedHashMap;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.StreamingOutput;
-import javax.ws.rs.ext.MessageBodyReader;
-import javax.ws.rs.ext.Providers;
+import jakarta.annotation.PostConstruct;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.FormParam;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedHashMap;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.StreamingOutput;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.Providers;
import org.talend.sdk.component.starter.server.configuration.StarterConfiguration;
import org.talend.sdk.component.starter.server.model.ErrorMessage;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/RRDEndpoint.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/RRDEndpoint.java
index b910dfcf6a278..daeffe91adfb1 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/RRDEndpoint.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/RRDEndpoint.java
@@ -15,8 +15,8 @@
*/
package org.talend.sdk.component.starter.server.front;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static java.util.stream.Collectors.toMap;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import java.io.InputStream;
import java.util.Collection;
@@ -27,17 +27,17 @@
import java.util.stream.IntStream;
import java.util.stream.Stream;
-import javax.annotation.PostConstruct;
-import javax.enterprise.context.ApplicationScoped;
-import javax.inject.Inject;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
+import jakarta.annotation.PostConstruct;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.DefaultValue;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
import org.rrd4j.core.FetchData;
import org.talend.sdk.component.starter.server.model.ErrorMessage;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/StarterApplication.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/StarterApplication.java
index 998927829053d..640dbf5e99d37 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/StarterApplication.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/StarterApplication.java
@@ -15,9 +15,9 @@
*/
package org.talend.sdk.component.starter.server.front;
-import javax.enterprise.context.Dependent;
-import javax.ws.rs.ApplicationPath;
-import javax.ws.rs.core.Application;
+import jakarta.enterprise.context.Dependent;
+import jakarta.ws.rs.ApplicationPath;
+import jakarta.ws.rs.core.Application;
@Dependent
@ApplicationPath("api")
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/js/IndexRedirector.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/js/IndexRedirector.java
index 09153ba0870aa..f939eff416523 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/js/IndexRedirector.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/front/js/IndexRedirector.java
@@ -18,14 +18,14 @@
import java.io.IOException;
import java.util.stream.Stream;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.annotation.WebFilter;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
+import jakarta.servlet.Filter;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.annotation.WebFilter;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletRequestWrapper;
// enforce the server to redirect to the client to handle the 404 to have a nice ui
@WebFilter(asyncSupported = true, urlPatterns = "/*")
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/model/ProjectModel.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/model/ProjectModel.java
index 3a350d3fb2bb6..45bbd01f3febb 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/model/ProjectModel.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/model/ProjectModel.java
@@ -17,8 +17,8 @@
import java.util.Collection;
-import javax.json.JsonObject;
-import javax.json.bind.annotation.JsonbProperty;
+import jakarta.json.JsonObject;
+import jakarta.json.bind.annotation.JsonbProperty;
import lombok.Data;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/ProjectGenerator.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/ProjectGenerator.java
index 41b33028498ae..17784dc5539dd 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/ProjectGenerator.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/ProjectGenerator.java
@@ -36,10 +36,10 @@
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
-import javax.annotation.PostConstruct;
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.event.Event;
-import javax.inject.Inject;
+import jakarta.annotation.PostConstruct;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.event.Event;
+import jakarta.inject.Inject;
import org.talend.sdk.component.starter.server.service.build.BuildGenerator;
import org.talend.sdk.component.starter.server.service.domain.Build;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/ReadmeGenerator.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/ReadmeGenerator.java
index edd54b0eaab39..c06f8b268f5f1 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/ReadmeGenerator.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/ReadmeGenerator.java
@@ -26,7 +26,7 @@
import java.util.Map;
import java.util.TreeMap;
-import javax.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.context.ApplicationScoped;
import org.talend.sdk.component.starter.server.service.facet.FacetGenerator;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/build/MavenBuildGenerator.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/build/MavenBuildGenerator.java
index 5f5f1e88380ac..ae670a8d3e8e2 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/build/MavenBuildGenerator.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/build/MavenBuildGenerator.java
@@ -27,9 +27,9 @@
import java.util.List;
import java.util.Map;
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.event.Observes;
-import javax.inject.Inject;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.event.Observes;
+import jakarta.inject.Inject;
import org.talend.sdk.component.starter.server.service.Resources;
import org.talend.sdk.component.starter.server.service.domain.Build;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/domain/ProjectRequest.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/domain/ProjectRequest.java
index 00496c6f3bc2a..efd1f9cd2b59b 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/domain/ProjectRequest.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/domain/ProjectRequest.java
@@ -19,7 +19,7 @@
import java.util.List;
import java.util.Map;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/beam/BeamFacet.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/beam/BeamFacet.java
index 75b4796e8ac8c..cf61a90b6388e 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/beam/BeamFacet.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/beam/BeamFacet.java
@@ -26,9 +26,9 @@
import java.util.Set;
import java.util.stream.Stream;
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.event.Observes;
-import javax.inject.Inject;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.event.Observes;
+import jakarta.inject.Inject;
import org.talend.sdk.component.starter.server.service.domain.Build;
import org.talend.sdk.component.starter.server.service.domain.Dependency;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/codenvy/CodenvyFacet.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/codenvy/CodenvyFacet.java
index e6fcd4854c345..1f06566e4d68f 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/codenvy/CodenvyFacet.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/codenvy/CodenvyFacet.java
@@ -19,9 +19,9 @@
import java.util.HashMap;
import java.util.stream.Stream;
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.event.Observes;
-import javax.inject.Inject;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.event.Observes;
+import jakarta.inject.Inject;
import org.talend.sdk.component.starter.server.service.domain.Build;
import org.talend.sdk.component.starter.server.service.domain.ProjectRequest;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/component/ComponentGenerator.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/component/ComponentGenerator.java
index 8256f968832e2..77f078b98a9f4 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/component/ComponentGenerator.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/component/ComponentGenerator.java
@@ -32,9 +32,9 @@
import java.util.TreeMap;
import java.util.stream.Stream;
-import javax.annotation.PostConstruct;
-import javax.enterprise.context.ApplicationScoped;
-import javax.inject.Inject;
+import jakarta.annotation.PostConstruct;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
import org.talend.sdk.component.starter.server.configuration.StarterConfiguration;
import org.talend.sdk.component.starter.server.service.domain.Build;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/testing/TalendComponentKitTesting.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/testing/TalendComponentKitTesting.java
index cac654763cad1..1d947dbe3ec6d 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/testing/TalendComponentKitTesting.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/testing/TalendComponentKitTesting.java
@@ -26,9 +26,9 @@
import java.util.Set;
import java.util.stream.Stream;
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.event.Observes;
-import javax.inject.Inject;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.event.Observes;
+import jakarta.inject.Inject;
import org.talend.sdk.component.starter.server.service.domain.Build;
import org.talend.sdk.component.starter.server.service.domain.Dependency;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/travis/TravisFacet.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/travis/TravisFacet.java
index 279d2475bfada..9515b0e428a42 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/travis/TravisFacet.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/travis/TravisFacet.java
@@ -18,8 +18,8 @@
import java.util.Collection;
import java.util.stream.Stream;
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.event.Observes;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.event.Observes;
import org.talend.sdk.component.starter.server.service.domain.Build;
import org.talend.sdk.component.starter.server.service.domain.ProjectRequest;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/util/NameConventions.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/util/NameConventions.java
index 199b0f6f9924f..0c01fd38aa328 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/util/NameConventions.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/util/NameConventions.java
@@ -22,7 +22,7 @@
import java.util.function.BiConsumer;
import java.util.stream.Stream;
-import javax.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.context.ApplicationScoped;
import org.talend.sdk.component.starter.server.service.Strings;
import org.talend.sdk.component.starter.server.service.domain.ProjectRequest;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/wadl/WADLFacet.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/wadl/WADLFacet.java
index 7bf719e83b6dd..9cfbc31cfdcb8 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/wadl/WADLFacet.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/facet/wadl/WADLFacet.java
@@ -23,8 +23,8 @@
import java.util.Collection;
import java.util.stream.Stream;
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.event.Observes;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.event.Observes;
import org.talend.sdk.component.starter.server.service.domain.Build;
import org.talend.sdk.component.starter.server.service.domain.Dependency;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/info/ServerInfo.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/info/ServerInfo.java
index bbd6cdb121105..13a4814f96689 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/info/ServerInfo.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/info/ServerInfo.java
@@ -32,18 +32,19 @@
import java.util.concurrent.ThreadFactory;
import java.util.function.Supplier;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.enterprise.context.ApplicationScoped;
-import javax.inject.Inject;
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.MediaType;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.MediaType;
+
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.talend.sdk.component.starter.server.configuration.StarterConfiguration;
import org.xml.sax.Attributes;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/json/JsonbProducer.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/json/JsonbProducer.java
index 7564b48415927..2d1f55f4f6b90 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/json/JsonbProducer.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/json/JsonbProducer.java
@@ -15,11 +15,11 @@
*/
package org.talend.sdk.component.starter.server.service.json;
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.inject.Disposes;
-import javax.enterprise.inject.Produces;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.inject.Disposes;
+import jakarta.enterprise.inject.Produces;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
import lombok.extern.slf4j.Slf4j;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/OpenAPIGenerator.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/OpenAPIGenerator.java
index 55150ffe893f2..26ffa52ce6ddc 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/OpenAPIGenerator.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/OpenAPIGenerator.java
@@ -32,12 +32,12 @@
import java.util.Optional;
import java.util.stream.Stream;
-import javax.enterprise.context.ApplicationScoped;
-import javax.inject.Inject;
-import javax.json.JsonObject;
-import javax.json.JsonString;
-import javax.json.JsonValue;
-import javax.json.bind.Jsonb;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
+import jakarta.json.bind.Jsonb;
import org.talend.sdk.component.starter.server.service.Strings;
import org.talend.sdk.component.starter.server.service.domain.Build;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/Contact.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/Contact.java
index faca5860c45a4..10220bb2070b0 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/Contact.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/Contact.java
@@ -15,7 +15,7 @@
*/
package org.talend.sdk.component.starter.server.service.openapi.model.common;
-import javax.json.bind.annotation.JsonbProperty;
+import jakarta.json.bind.annotation.JsonbProperty;
import lombok.Data;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/ExternalDocs.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/ExternalDocs.java
index 4101a83b5b12b..6f8aef321bc54 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/ExternalDocs.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/ExternalDocs.java
@@ -15,7 +15,7 @@
*/
package org.talend.sdk.component.starter.server.service.openapi.model.common;
-import javax.json.bind.annotation.JsonbProperty;
+import jakarta.json.bind.annotation.JsonbProperty;
import lombok.Data;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/Info.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/Info.java
index f69f82292bb73..5a043db12782c 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/Info.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/Info.java
@@ -15,7 +15,7 @@
*/
package org.talend.sdk.component.starter.server.service.openapi.model.common;
-import javax.json.bind.annotation.JsonbProperty;
+import jakarta.json.bind.annotation.JsonbProperty;
import lombok.Data;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/License.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/License.java
index 9b72160b3b1d3..f356db3854472 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/License.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/License.java
@@ -15,7 +15,7 @@
*/
package org.talend.sdk.component.starter.server.service.openapi.model.common;
-import javax.json.bind.annotation.JsonbProperty;
+import jakarta.json.bind.annotation.JsonbProperty;
import lombok.Data;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/ParameterBase.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/ParameterBase.java
index 2fe4754531d84..0ebb3a5d9b30b 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/ParameterBase.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/ParameterBase.java
@@ -15,7 +15,7 @@
*/
package org.talend.sdk.component.starter.server.service.openapi.model.common;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import lombok.Data;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/Tag.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/Tag.java
index 47cd02fac44c0..da3763778018a 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/Tag.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/common/Tag.java
@@ -15,7 +15,7 @@
*/
package org.talend.sdk.component.starter.server.service.openapi.model.common;
-import javax.json.bind.annotation.JsonbProperty;
+import jakarta.json.bind.annotation.JsonbProperty;
import lombok.Data;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/Components.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/Components.java
index f8fa9c5f03f21..2c992cc0bd91e 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/Components.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/Components.java
@@ -17,7 +17,7 @@
import java.util.Map;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import lombok.Data;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/MediaType.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/MediaType.java
index 7ce8eb87cadc0..01ab4dd474ec8 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/MediaType.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/MediaType.java
@@ -17,7 +17,7 @@
import java.util.Map;
-import javax.json.JsonValue;
+import jakarta.json.JsonValue;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/OpenAPI.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/OpenAPI.java
index 36d9bed9fbd39..7f9d59a04500a 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/OpenAPI.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/OpenAPI.java
@@ -20,7 +20,7 @@
import java.util.List;
import java.util.Map;
-import javax.json.bind.annotation.JsonbProperty;
+import jakarta.json.bind.annotation.JsonbProperty;
import org.talend.sdk.component.starter.server.service.openapi.model.ApiModel;
import org.talend.sdk.component.starter.server.service.openapi.model.common.ExternalDocs;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/Operation.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/Operation.java
index b117ae2d5ea83..f21fb9f06ba18 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/Operation.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/Operation.java
@@ -18,7 +18,7 @@
import java.util.List;
import java.util.Map;
-import javax.json.JsonValue;
+import jakarta.json.JsonValue;
import org.talend.sdk.component.starter.server.service.openapi.model.common.OperationBase;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/Path.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/Path.java
index 606ffcedca0c8..1660489409c74 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/Path.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/Path.java
@@ -17,7 +17,7 @@
import java.util.List;
-import javax.json.bind.annotation.JsonbProperty;
+import jakarta.json.bind.annotation.JsonbProperty;
import lombok.Data;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/Reference.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/Reference.java
index bcb24d491c4b3..81d4a48b4272d 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/Reference.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/Reference.java
@@ -15,7 +15,7 @@
*/
package org.talend.sdk.component.starter.server.service.openapi.model.openapi;
-import javax.json.bind.annotation.JsonbProperty;
+import jakarta.json.bind.annotation.JsonbProperty;
import lombok.Data;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/Server.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/Server.java
index e5d611705cb03..d386bbe8f4dbd 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/Server.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/Server.java
@@ -17,7 +17,7 @@
import java.util.Map;
-import javax.json.bind.annotation.JsonbProperty;
+import jakarta.json.bind.annotation.JsonbProperty;
import lombok.Data;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/ServerVariable.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/ServerVariable.java
index 0c76045dbef70..c31df43d52796 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/ServerVariable.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/openapi/ServerVariable.java
@@ -17,7 +17,7 @@
import java.util.List;
-import javax.json.bind.annotation.JsonbProperty;
+import jakarta.json.bind.annotation.JsonbProperty;
import lombok.Data;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/swagger/Operation.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/swagger/Operation.java
index a641037206b73..53807c3bbbb17 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/swagger/Operation.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/swagger/Operation.java
@@ -18,7 +18,7 @@
import java.util.List;
import java.util.Map;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.starter.server.service.openapi.model.common.OperationBase;
import org.talend.sdk.component.starter.server.service.openapi.model.openapi.Parameter;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/swagger/Parameter.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/swagger/Parameter.java
index ac2b687cf4257..8c94bb755d76c 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/swagger/Parameter.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/swagger/Parameter.java
@@ -15,8 +15,8 @@
*/
package org.talend.sdk.component.starter.server.service.openapi.model.swagger;
-import javax.json.JsonObject;
-import javax.json.bind.annotation.JsonbProperty;
+import jakarta.json.JsonObject;
+import jakarta.json.bind.annotation.JsonbProperty;
import org.talend.sdk.component.starter.server.service.openapi.model.common.ParameterBase;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/swagger/SwaggerAPI.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/swagger/SwaggerAPI.java
index 4b10f4dd3213e..253c6153e048d 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/swagger/SwaggerAPI.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/openapi/model/swagger/SwaggerAPI.java
@@ -22,7 +22,7 @@
import java.util.Map;
import java.util.Objects;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.starter.server.service.openapi.model.ApiModel;
import org.talend.sdk.component.starter.server.service.openapi.model.common.ExternalDocs;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/rrd/RRDConfig.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/rrd/RRDConfig.java
index 299131ddbcf40..11544daf8b3d5 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/rrd/RRDConfig.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/rrd/RRDConfig.java
@@ -18,8 +18,8 @@
import java.util.List;
import java.util.Optional;
-import javax.enterprise.context.ApplicationScoped;
-import javax.inject.Inject;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
import org.eclipse.microprofile.config.inject.ConfigProperty;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/rrd/RRDStorage.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/rrd/RRDStorage.java
index f55b9fb503b79..9bdae5340a08b 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/rrd/RRDStorage.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/rrd/RRDStorage.java
@@ -39,11 +39,11 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
-import javax.annotation.PreDestroy;
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.context.Initialized;
-import javax.enterprise.event.Observes;
-import javax.inject.Inject;
+import jakarta.annotation.PreDestroy;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.context.Initialized;
+import jakarta.enterprise.event.Observes;
+import jakarta.inject.Inject;
import org.rrd4j.DsType;
import org.rrd4j.core.ArcDef;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/statistic/StatisticService.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/statistic/StatisticService.java
index a0fad2e05cd4a..ffbbed8ffdd99 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/statistic/StatisticService.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/statistic/StatisticService.java
@@ -25,15 +25,15 @@
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.enterprise.context.ApplicationScoped;
-import javax.enterprise.event.Event;
-import javax.enterprise.event.Observes;
-import javax.inject.Inject;
-import javax.json.JsonObject;
-import javax.json.JsonValue;
-import javax.json.bind.Jsonb;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.event.Event;
+import jakarta.enterprise.event.Observes;
+import jakarta.inject.Inject;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonValue;
+import jakarta.json.bind.Jsonb;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.slf4j.Logger;
diff --git a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/template/TemplateRenderer.java b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/template/TemplateRenderer.java
index c6ba36caca111..d9aa33c8eee6c 100644
--- a/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/template/TemplateRenderer.java
+++ b/component-starter-server/src/main/java/org/talend/sdk/component/starter/server/service/template/TemplateRenderer.java
@@ -24,7 +24,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
-import javax.enterprise.context.ApplicationScoped;
+import jakarta.enterprise.context.ApplicationScoped;
import com.github.mustachejava.DefaultMustacheFactory;
import com.github.mustachejava.Mustache;
diff --git a/component-starter-server/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer b/component-starter-server/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer
similarity index 100%
rename from component-starter-server/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer
rename to component-starter-server/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer
diff --git a/component-starter-server/src/main/resources/generator/component/Processor.mustache b/component-starter-server/src/main/resources/generator/component/Processor.mustache
index a4946ee75f81e..f8391a6ebb377 100644
--- a/component-starter-server/src/main/resources/generator/component/Processor.mustache
+++ b/component-starter-server/src/main/resources/generator/component/Processor.mustache
@@ -4,8 +4,8 @@ import static org.talend.sdk.component.api.component.Icon.IconType.CUSTOM;
import java.io.Serializable;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import org.talend.sdk.component.api.component.Icon;
import org.talend.sdk.component.api.component.Version;
diff --git a/component-starter-server/src/main/resources/generator/component/Source.mustache b/component-starter-server/src/main/resources/generator/component/Source.mustache
index d71bb6b9e270f..0b8893df125c0 100644
--- a/component-starter-server/src/main/resources/generator/component/Source.mustache
+++ b/component-starter-server/src/main/resources/generator/component/Source.mustache
@@ -2,8 +2,8 @@ package {{package}};
import java.io.Serializable;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.input.Producer;
diff --git a/component-starter-server/src/main/resources/generator/openapi/client.mustache b/component-starter-server/src/main/resources/generator/openapi/client.mustache
index 5393c72f8049f..bcd03bce36b1f 100644
--- a/component-starter-server/src/main/resources/generator/openapi/client.mustache
+++ b/component-starter-server/src/main/resources/generator/openapi/client.mustache
@@ -5,7 +5,7 @@ package {{packageName}}.client;
import java.util.List;
{{/importList}}
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.service.http.HttpClient;
{{#importAPI}}
diff --git a/component-starter-server/src/main/resources/generator/openapi/dataset.mustache b/component-starter-server/src/main/resources/generator/openapi/dataset.mustache
index 1e1737f95bf53..73a89252db1c4 100644
--- a/component-starter-server/src/main/resources/generator/openapi/dataset.mustache
+++ b/component-starter-server/src/main/resources/generator/openapi/dataset.mustache
@@ -6,7 +6,7 @@ import java.util.List;
{{/importList}}
import java.io.Serializable;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.component.Icon;
import org.talend.sdk.component.api.component.Version;
diff --git a/component-starter-server/src/main/resources/generator/openapi/source.mustache b/component-starter-server/src/main/resources/generator/openapi/source.mustache
index 1df5f525e8542..b94b799c8a1aa 100644
--- a/component-starter-server/src/main/resources/generator/openapi/source.mustache
+++ b/component-starter-server/src/main/resources/generator/openapi/source.mustache
@@ -2,7 +2,7 @@ package {{packageName}}.source;
import java.io.Serializable;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.component.Icon;
import org.talend.sdk.component.api.component.Version;
diff --git a/component-starter-server/src/main/resources/meecrowave.properties b/component-starter-server/src/main/resources/meecrowave.properties
index ee7c9d9940206..23554afaf7de0 100644
--- a/component-starter-server/src/main/resources/meecrowave.properties
+++ b/component-starter-server/src/main/resources/meecrowave.properties
@@ -14,6 +14,10 @@
connector.attributes.compression = on
# jars which don't need to be scanned (optional config but makes logs easier to read and startup a bit faster)
+# smallrye-config is excluded to avoid an AmbiguousResolutionException: its own portable extension
+# already registers io.smallrye.config.inject.ConfigProducer as a synthetic bean, so implicit CDI
+# scanning of the same class produces a duplicate bean for every @ConfigProperty injection point
+# (QTDI-3358 jakarta migration).
scanning-exclude = apiguardian,brave,kafka,lz4,talend-icon,zipkin,container-core,component-runtime,\
beam,paranamer,joda-time,avro,objenesis,xz,snappy,component-spi,component-api,tomcat-websocket,\
-dirgra,bytelist,invokebinder,jcodings,joni,modulator,options,stax-ex,JavaEWAH,jsch,txw2,common-java5
+dirgra,bytelist,invokebinder,jcodings,joni,modulator,options,stax-ex,JavaEWAH,jsch,txw2,common-java5,smallrye-config
diff --git a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/ProjectResourceTest.java b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/ProjectResourceTest.java
index a8b988039e961..b8a6e70c2877c 100644
--- a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/ProjectResourceTest.java
+++ b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/ProjectResourceTest.java
@@ -37,21 +37,27 @@
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
-import javax.inject.Inject;
-import javax.json.Json;
-import javax.json.bind.Jsonb;
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.MediaType;
-
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import jakarta.inject.Inject;
+import jakarta.json.Json;
+import jakarta.json.bind.Jsonb;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.MediaType;
+
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
import org.talend.sdk.component.starter.server.model.FactoryConfiguration;
import org.talend.sdk.component.starter.server.model.ProjectModel;
import org.talend.sdk.component.starter.server.service.info.ServerInfo;
import org.talend.sdk.component.starter.server.test.Client;
-@MonoMeecrowaveConfig
+// scanningExcludes="smallrye-config" avoids CDI AmbiguousResolutionException from SmallRye Config's
+// ConfigProducer bean being registered twice (same root cause/fix as component-server's 19 converted
+// classes - see QTDI-3358 notes); @MonoMeecrowaveConfig has no scanningExcludes equivalent, hence the
+// switch to per-class @MeecrowaveConfig + @TestInstance(PER_CLASS) (one container per test class).
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
@Client.Active
class ProjectResourceTest {
diff --git a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/RRDEndpointTest.java b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/RRDEndpointTest.java
index 813def777ce34..96e852e4470ed 100644
--- a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/RRDEndpointTest.java
+++ b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/RRDEndpointTest.java
@@ -15,23 +15,29 @@
*/
package org.talend.sdk.component.starter.server.front;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import static java.lang.Thread.sleep;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
import java.util.Collection;
import java.util.Map;
-import javax.ws.rs.client.Entity;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.MediaType;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.MediaType;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.Timeout;
import org.talend.sdk.component.starter.server.model.ProjectModel;
import org.talend.sdk.component.starter.server.test.Client;
-@MonoMeecrowaveConfig
+// scanningExcludes="smallrye-config" avoids CDI AmbiguousResolutionException from SmallRye Config's
+// ConfigProducer bean being registered twice (same root cause/fix as component-server's 19 converted
+// classes - see QTDI-3358 notes); @MonoMeecrowaveConfig has no scanningExcludes equivalent, hence the
+// switch to per-class @MeecrowaveConfig + @TestInstance(PER_CLASS) (one container per test class).
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
@Client.Active
class RRDEndpointTest {
diff --git a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/ApiDemoEndpointsTest.java b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/ApiDemoEndpointsTest.java
index f994bcad12b74..663ae59a7ec8f 100644
--- a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/ApiDemoEndpointsTest.java
+++ b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/ApiDemoEndpointsTest.java
@@ -15,9 +15,9 @@
*/
package org.talend.sdk.component.starter.server.front.apidemo;
-import static javax.ws.rs.client.Entity.entity;
-import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
-import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM_TYPE;
+import static jakarta.ws.rs.client.Entity.entity;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM_TYPE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -26,19 +26,25 @@
import java.util.HashMap;
import java.util.Map;
-import javax.json.JsonArray;
-import javax.json.JsonObject;
-import javax.ws.rs.client.WebTarget;
-import javax.ws.rs.core.GenericType;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonObject;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.GenericType;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
import org.talend.sdk.component.starter.server.test.Client;
import lombok.extern.slf4j.Slf4j;
@Slf4j
-@MonoMeecrowaveConfig
+// scanningExcludes="smallrye-config" avoids CDI AmbiguousResolutionException from SmallRye Config's
+// ConfigProducer bean being registered twice (same root cause/fix as component-server's 19 converted
+// classes - see QTDI-3358 notes); @MonoMeecrowaveConfig has no scanningExcludes equivalent, hence the
+// switch to per-class @MeecrowaveConfig + @TestInstance(PER_CLASS) (one container per test class).
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
@Client.Active
class ApiDemoEndpointsTest {
diff --git a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/output/MockOutput.java b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/output/MockOutput.java
index c5d17be1d3b35..2d58465d5daab 100644
--- a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/output/MockOutput.java
+++ b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/output/MockOutput.java
@@ -20,10 +20,10 @@
import java.io.Serializable;
-import javax.annotation.PostConstruct;
-import javax.json.JsonBuilderFactory;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
+import jakarta.annotation.PostConstruct;
+import jakarta.json.JsonBuilderFactory;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonObjectBuilder;
import org.talend.sdk.component.api.component.Icon;
import org.talend.sdk.component.api.component.Version;
diff --git a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/output/Reject.java b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/output/Reject.java
index 4957ee7f9e323..0fbf7c24c45ef 100644
--- a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/output/Reject.java
+++ b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/output/Reject.java
@@ -17,7 +17,7 @@
import java.io.Serializable;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import lombok.AllArgsConstructor;
import lombok.Data;
diff --git a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/service/MockTableService.java b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/service/MockTableService.java
index 05ec55d5bb1e8..e63c80e31f504 100644
--- a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/service/MockTableService.java
+++ b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/service/MockTableService.java
@@ -25,7 +25,7 @@
import java.net.URL;
import java.util.stream.Stream;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.service.Service;
diff --git a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/service/http/TableApiClient.java b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/service/http/TableApiClient.java
index a06584d7d7172..bf747ac19155c 100644
--- a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/service/http/TableApiClient.java
+++ b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/service/http/TableApiClient.java
@@ -17,8 +17,8 @@
import java.util.List;
-import javax.json.JsonArray;
-import javax.json.JsonObject;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.meta.Documentation;
import org.talend.sdk.component.api.service.http.Codec;
diff --git a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/source/MockTableMapper.java b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/source/MockTableMapper.java
index d062406c9c104..1c037635cbfd8 100644
--- a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/source/MockTableMapper.java
+++ b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/source/MockTableMapper.java
@@ -24,7 +24,7 @@
import java.util.Objects;
import java.util.stream.LongStream;
-import javax.annotation.PostConstruct;
+import jakarta.annotation.PostConstruct;
import org.talend.sdk.component.api.component.Icon;
import org.talend.sdk.component.api.component.Version;
diff --git a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/source/MockTableSource.java b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/source/MockTableSource.java
index 069ae760c5012..141dcad9d704e 100644
--- a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/source/MockTableSource.java
+++ b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/front/apidemo/component/source/MockTableSource.java
@@ -21,10 +21,10 @@
import java.io.Serializable;
-import javax.annotation.PostConstruct;
-import javax.json.JsonArray;
-import javax.json.JsonObject;
-import javax.json.JsonValue;
+import jakarta.annotation.PostConstruct;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonValue;
import org.talend.sdk.component.api.base.BufferizedProducerSupport;
import org.talend.sdk.component.api.configuration.Option;
diff --git a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/service/facet/component/ComponentGeneratorConfigurationTest.java b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/service/facet/component/ComponentGeneratorConfigurationTest.java
index 8cf67a3f20bd6..f3958d19ef7a6 100644
--- a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/service/facet/component/ComponentGeneratorConfigurationTest.java
+++ b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/service/facet/component/ComponentGeneratorConfigurationTest.java
@@ -24,9 +24,10 @@
import java.util.HashMap;
import java.util.stream.Stream;
-import javax.inject.Inject;
+import jakarta.inject.Inject;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
+import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.talend.sdk.component.starter.server.service.domain.ProjectRequest;
@@ -34,7 +35,12 @@
import lombok.Data;
-@MonoMeecrowaveConfig
+// scanningExcludes="smallrye-config" avoids CDI AmbiguousResolutionException from SmallRye Config's
+// ConfigProducer bean being registered twice (same root cause/fix as component-server's 19 converted
+// classes - see QTDI-3358 notes); @MonoMeecrowaveConfig has no scanningExcludes equivalent, hence the
+// switch to per-class @MeecrowaveConfig + @TestInstance(PER_CLASS) (one container per test class).
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
class ComponentGeneratorConfigurationTest {
@Inject
diff --git a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/service/facet/component/ComponentGeneratorTest.java b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/service/facet/component/ComponentGeneratorTest.java
index 4e49bcbf404c8..477136701a7e3 100644
--- a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/service/facet/component/ComponentGeneratorTest.java
+++ b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/service/facet/component/ComponentGeneratorTest.java
@@ -37,15 +37,21 @@
import java.util.Map;
import java.util.Set;
-import javax.inject.Inject;
+import jakarta.inject.Inject;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
import org.talend.sdk.component.starter.server.service.domain.Build;
import org.talend.sdk.component.starter.server.service.domain.ProjectRequest;
import org.talend.sdk.component.starter.server.service.facet.FacetGenerator;
-@MonoMeecrowaveConfig
+// scanningExcludes="smallrye-config" avoids CDI AmbiguousResolutionException from SmallRye Config's
+// ConfigProducer bean being registered twice (same root cause/fix as component-server's 19 converted
+// classes - see QTDI-3358 notes); @MonoMeecrowaveConfig has no scanningExcludes equivalent, hence the
+// switch to per-class @MeecrowaveConfig + @TestInstance(PER_CLASS) (one container per test class).
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
class ComponentGeneratorTest {
@Inject
diff --git a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/service/facet/test/TalendComponentKitTestingTest.java b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/service/facet/test/TalendComponentKitTestingTest.java
index 8b96a22f9eadc..08298f1ff86be 100644
--- a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/service/facet/test/TalendComponentKitTestingTest.java
+++ b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/service/facet/test/TalendComponentKitTestingTest.java
@@ -27,16 +27,22 @@
import java.util.HashMap;
import java.util.Set;
-import javax.inject.Inject;
+import jakarta.inject.Inject;
-import org.apache.meecrowave.junit5.MonoMeecrowaveConfig;
+import org.apache.meecrowave.junit5.MeecrowaveConfig;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
import org.talend.sdk.component.starter.server.service.domain.Build;
import org.talend.sdk.component.starter.server.service.domain.ProjectRequest;
import org.talend.sdk.component.starter.server.service.facet.testing.TalendComponentKitTesting;
import org.talend.sdk.component.starter.server.service.info.ServerInfo;
-@MonoMeecrowaveConfig
+// scanningExcludes="smallrye-config" avoids CDI AmbiguousResolutionException from SmallRye Config's
+// ConfigProducer bean being registered twice (same root cause/fix as component-server's 19 converted
+// classes - see QTDI-3358 notes); @MonoMeecrowaveConfig has no scanningExcludes equivalent, hence the
+// switch to per-class @MeecrowaveConfig + @TestInstance(PER_CLASS) (one container per test class).
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@MeecrowaveConfig(scanningExcludes = "smallrye-config")
class TalendComponentKitTestingTest {
@Inject
diff --git a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/test/Client.java b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/test/Client.java
index 8d487bac15764..48e2e109bf9b7 100644
--- a/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/test/Client.java
+++ b/component-starter-server/src/test/java/org/talend/sdk/component/starter/server/test/Client.java
@@ -22,9 +22,9 @@
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
-import javax.enterprise.inject.spi.CDI;
-import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.client.WebTarget;
+import jakarta.enterprise.inject.spi.CDI;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.WebTarget;
import org.apache.meecrowave.Meecrowave;
import org.junit.jupiter.api.extension.AfterAllCallback;
@@ -48,25 +48,25 @@ public static class ClientRuleExtension implements BeforeAllCallback, AfterAllCa
@Override
public void afterAll(final ExtensionContext context) {
- ((javax.ws.rs.client.Client) context.getStore(NAMESPACE).get(javax.ws.rs.client.Client.class.getName()))
+ ((jakarta.ws.rs.client.Client) context.getStore(NAMESPACE).get(jakarta.ws.rs.client.Client.class.getName()))
.close();
}
@Override
public void beforeAll(final ExtensionContext context) {
- final javax.ws.rs.client.Client client = ClientBuilder.newClient();
- context.getStore(NAMESPACE).put(javax.ws.rs.client.Client.class.getName(), client);
+ final jakarta.ws.rs.client.Client client = ClientBuilder.newClient();
+ context.getStore(NAMESPACE).put(jakarta.ws.rs.client.Client.class.getName(), client);
context.getStore(NAMESPACE).put(WebTarget.class.getName(), target(client));
}
- private WebTarget target(final javax.ws.rs.client.Client client) {
+ private WebTarget target(final jakarta.ws.rs.client.Client client) {
final Meecrowave.Builder config = CDI.current().select(Meecrowave.Builder.class).get();
return client.target("http://localhost:" + config.getHttpPort() + "/api");
}
@Override
public boolean supports(final Class> type) {
- return WebTarget.class == type || javax.ws.rs.client.Client.class == type;
+ return WebTarget.class == type || jakarta.ws.rs.client.Client.class == type;
}
@Override
diff --git a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/genericSource/MycompMapper.java b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/genericSource/MycompMapper.java
index 99b2c8358443d..2cff348d10b9b 100644
--- a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/genericSource/MycompMapper.java
+++ b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/genericSource/MycompMapper.java
@@ -2,8 +2,8 @@
import java.io.Serializable;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.input.Producer;
diff --git a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/genericSource/MycompSource.java b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/genericSource/MycompSource.java
index 6cce2461cb179..76a878f767a83 100644
--- a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/genericSource/MycompSource.java
+++ b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/genericSource/MycompSource.java
@@ -2,8 +2,8 @@
import java.io.Serializable;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.input.Producer;
diff --git a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/genericStreamMapper/MycompSource.java b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/genericStreamMapper/MycompSource.java
index 238e445db9429..6d3a743f3c77e 100644
--- a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/genericStreamMapper/MycompSource.java
+++ b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/genericStreamMapper/MycompSource.java
@@ -1,7 +1,7 @@
package com.foo.source;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import com.foo.service.TestService;
diff --git a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/isolatedProcessor/TProcProcessor.java b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/isolatedProcessor/TProcProcessor.java
index 46af9c2740d73..55be6d37a815e 100644
--- a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/isolatedProcessor/TProcProcessor.java
+++ b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/isolatedProcessor/TProcProcessor.java
@@ -4,8 +4,8 @@
import java.io.Serializable;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import org.talend.sdk.component.api.component.Icon;
import org.talend.sdk.component.api.component.Version;
diff --git a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/processorGenericInput/TProcProcessor.java b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/processorGenericInput/TProcProcessor.java
index 2fe1019d59094..a684697f2383f 100644
--- a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/processorGenericInput/TProcProcessor.java
+++ b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/processorGenericInput/TProcProcessor.java
@@ -4,8 +4,8 @@
import java.io.Serializable;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import org.talend.sdk.component.api.component.Icon;
import org.talend.sdk.component.api.component.Version;
diff --git a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/processorGenericOutput/TProcProcessor.java b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/processorGenericOutput/TProcProcessor.java
index fbd88b91cb4d3..fd7a59208a3b5 100644
--- a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/processorGenericOutput/TProcProcessor.java
+++ b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/processorGenericOutput/TProcProcessor.java
@@ -4,8 +4,8 @@
import java.io.Serializable;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import org.talend.sdk.component.api.component.Icon;
import org.talend.sdk.component.api.component.Version;
diff --git a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/processorInput/TProcProcessor.java b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/processorInput/TProcProcessor.java
index 1fe27623b3f11..14c16dd842815 100644
--- a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/processorInput/TProcProcessor.java
+++ b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/processorInput/TProcProcessor.java
@@ -4,8 +4,8 @@
import java.io.Serializable;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import org.talend.sdk.component.api.component.Icon;
import org.talend.sdk.component.api.component.Version;
diff --git a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/processorOutput/TProcProcessor.java b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/processorOutput/TProcProcessor.java
index c4b60a1a96a4c..bcdb5d826f107 100644
--- a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/processorOutput/TProcProcessor.java
+++ b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/processorOutput/TProcProcessor.java
@@ -4,8 +4,8 @@
import java.io.Serializable;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import org.talend.sdk.component.api.component.Icon;
import org.talend.sdk.component.api.component.Version;
diff --git a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/source/MycompSource.java b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/source/MycompSource.java
index 9dec3174eb0b1..9ed2ee1c81276 100644
--- a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/source/MycompSource.java
+++ b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/source/MycompSource.java
@@ -2,8 +2,8 @@
import java.io.Serializable;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.input.Producer;
diff --git a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/sourceComplexConfiguration/MycompSource.java b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/sourceComplexConfiguration/MycompSource.java
index bafc31c10c1ab..6ba7983acf4f1 100644
--- a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/sourceComplexConfiguration/MycompSource.java
+++ b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/sourceComplexConfiguration/MycompSource.java
@@ -2,8 +2,8 @@
import java.io.Serializable;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import org.talend.sdk.component.api.configuration.Option;
import org.talend.sdk.component.api.input.Producer;
diff --git a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/standardProcessor/TProcProcessor.java b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/standardProcessor/TProcProcessor.java
index 20cd45a88a14e..e4247b9644dc7 100644
--- a/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/standardProcessor/TProcProcessor.java
+++ b/component-starter-server/src/test/resources/generated/ComponentGeneratorTest/standardProcessor/TProcProcessor.java
@@ -4,8 +4,8 @@
import java.io.Serializable;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import org.talend.sdk.component.api.component.Icon;
import org.talend.sdk.component.api.component.Version;
diff --git a/component-starter-server/src/test/resources/generated/ProjectResourceTest/openapi/APIClient.java b/component-starter-server/src/test/resources/generated/ProjectResourceTest/openapi/APIClient.java
index 8a1eb48f8df19..48f493b4132d2 100644
--- a/component-starter-server/src/test/resources/generated/ProjectResourceTest/openapi/APIClient.java
+++ b/component-starter-server/src/test/resources/generated/ProjectResourceTest/openapi/APIClient.java
@@ -1,6 +1,6 @@
package com.test.openapi.client;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.service.http.HttpClient;
import org.talend.sdk.component.api.service.http.Path;
diff --git a/component-starter-server/src/test/resources/generated/ProjectResourceTest/openapi/APIDataSet.java b/component-starter-server/src/test/resources/generated/ProjectResourceTest/openapi/APIDataSet.java
index 8698ba1a7c904..81c112215c75a 100644
--- a/component-starter-server/src/test/resources/generated/ProjectResourceTest/openapi/APIDataSet.java
+++ b/component-starter-server/src/test/resources/generated/ProjectResourceTest/openapi/APIDataSet.java
@@ -2,7 +2,7 @@
import java.io.Serializable;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.component.Icon;
import org.talend.sdk.component.api.component.Version;
diff --git a/component-starter-server/src/test/resources/generated/ProjectResourceTest/openapi/APISource.java b/component-starter-server/src/test/resources/generated/ProjectResourceTest/openapi/APISource.java
index ba707c6537aae..5292fcbb40b34 100644
--- a/component-starter-server/src/test/resources/generated/ProjectResourceTest/openapi/APISource.java
+++ b/component-starter-server/src/test/resources/generated/ProjectResourceTest/openapi/APISource.java
@@ -2,7 +2,7 @@
import java.io.Serializable;
-import javax.json.JsonObject;
+import jakarta.json.JsonObject;
import org.talend.sdk.component.api.component.Icon;
import org.talend.sdk.component.api.component.Version;
diff --git a/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/BaseIOHandler.java b/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/BaseIOHandler.java
index 136e3c7a4532b..bc2792e782e16 100644
--- a/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/BaseIOHandler.java
+++ b/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/BaseIOHandler.java
@@ -23,7 +23,7 @@
import java.util.Queue;
import java.util.TreeMap;
-import javax.json.bind.Jsonb;
+import jakarta.json.bind.Jsonb;
import org.talend.sdk.component.api.service.record.RecordBuilderFactory;
import org.talend.sdk.component.runtime.record.RecordConverters;
diff --git a/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/InputsHandler.java b/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/InputsHandler.java
index eef926ee05133..4aaa98dd3aad2 100644
--- a/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/InputsHandler.java
+++ b/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/InputsHandler.java
@@ -17,8 +17,8 @@
import java.util.Map;
-import javax.json.JsonValue;
-import javax.json.bind.Jsonb;
+import jakarta.json.JsonValue;
+import jakarta.json.bind.Jsonb;
import org.talend.sdk.component.api.record.Record;
import org.talend.sdk.component.runtime.output.InputFactory;
@@ -44,22 +44,14 @@ public InputFactory asInputFactory() {
if (value instanceof Record) {
return value;
}
- final Object convertedValue;
- final MappingMeta mappingMeta;
- mappingMeta = registry.find(value.getClass());
+ final MappingMeta mappingMeta = registry.find(value.getClass());
if (mappingMeta.isLinearMapping()) {
return mappingMeta.newRecord(value, recordBuilderMapper);
- } else {
- if (value instanceof javax.json.JsonValue) {
- if (JsonValue.NULL == value) { // JsonObject cant take a JsonValue so pass null
- return null;
- }
- convertedValue = value.toString();
- } else {
- convertedValue = jsonb.toJson(value);
- }
}
-
+ if (JsonValue.NULL == value) { // JsonObject cant take a JsonValue so pass null
+ return null;
+ }
+ final Object convertedValue = value instanceof JsonValue ? value.toString() : jsonb.toJson(value);
return converters.toRecord(registry, convertedValue, () -> jsonb, () -> recordBuilderMapper);
};
}
diff --git a/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/OutputsHandler.java b/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/OutputsHandler.java
index b8de1ad38ee4e..dcaf32d4b5aaa 100644
--- a/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/OutputsHandler.java
+++ b/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/OutputsHandler.java
@@ -18,7 +18,7 @@
import java.util.Iterator;
import java.util.Map;
-import javax.json.bind.Jsonb;
+import jakarta.json.bind.Jsonb;
import org.talend.sdk.component.api.processor.MultiOutputIterator;
import org.talend.sdk.component.api.processor.OutputEmitter;
@@ -102,7 +102,7 @@ public OutputFactory asOutputFactoryForGuessSchema() {
return name -> value -> {
final BaseIOHandler.IO ref = connections.get(getActualName(name));
if (ref != null && value != null) {
- if (value instanceof javax.json.JsonValue) {
+ if (value instanceof jakarta.json.JsonValue) {
ref.add(jsonb.fromJson(value.toString(), ref.getType()));
} else if (value instanceof Record rec) {
ref.add(rec.getSchema());
@@ -118,7 +118,7 @@ public OutputFactory asOutputFactoryForGuessSchema() {
private Object convert(final Object value, final BaseIOHandler.IO ref) {
if (value == null) {
return null;
- } else if (value instanceof javax.json.JsonValue) {
+ } else if (value instanceof jakarta.json.JsonValue) {
return jsonb.fromJson(value.toString(), ref.getType());
} else if (value instanceof Record rec) {
return registry.find(ref.getType()).newInstance(rec);
diff --git a/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/beam/LoopState.java b/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/beam/LoopState.java
index 3110aa63f2204..4de65f772fdee 100644
--- a/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/beam/LoopState.java
+++ b/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/beam/LoopState.java
@@ -26,8 +26,8 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbConfig;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbConfig;
import org.talend.sdk.component.api.record.Record;
import org.talend.sdk.component.api.service.record.RecordBuilderFactory;
diff --git a/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/record/DiRecordVisitor.java b/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/record/DiRecordVisitor.java
index aac7bb6fe9be1..8c6cd0268676f 100644
--- a/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/record/DiRecordVisitor.java
+++ b/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/record/DiRecordVisitor.java
@@ -47,10 +47,10 @@
import java.util.Set;
import java.util.stream.Collectors;
-import javax.json.Json;
-import javax.json.bind.JsonbConfig;
-import javax.json.bind.spi.JsonbProvider;
-import javax.json.spi.JsonProvider;
+import jakarta.json.Json;
+import jakarta.json.bind.JsonbConfig;
+import jakarta.json.bind.spi.JsonbProvider;
+import jakarta.json.spi.JsonProvider;
import org.dom4j.DocumentException;
import org.talend.sdk.component.api.record.Record;
diff --git a/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/record/DiRowStructVisitor.java b/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/record/DiRowStructVisitor.java
index ebce904c91446..6a47a1febe1db 100644
--- a/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/record/DiRowStructVisitor.java
+++ b/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/record/DiRowStructVisitor.java
@@ -52,8 +52,8 @@
import java.util.Set;
import java.util.stream.Collectors;
-import javax.json.bind.Jsonb;
-import javax.json.bind.spi.JsonbProvider;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.spi.JsonbProvider;
import org.talend.sdk.component.api.record.Record;
import org.talend.sdk.component.api.record.Record.Builder;
diff --git a/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/schema/TaCoKitGuessSchema.java b/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/schema/TaCoKitGuessSchema.java
index e1a98eaf68035..82ebbb11f2ebf 100644
--- a/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/schema/TaCoKitGuessSchema.java
+++ b/component-studio/component-runtime-di/src/main/java/org/talend/sdk/component/runtime/di/schema/TaCoKitGuessSchema.java
@@ -44,11 +44,11 @@
import java.util.stream.IntStream;
import java.util.stream.Stream;
-import javax.json.JsonNumber;
-import javax.json.JsonObject;
-import javax.json.JsonValue;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonValue;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
import org.talend.sdk.component.api.exception.ComponentException;
import org.talend.sdk.component.api.exception.DiscoverSchemaException;
diff --git a/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/InputsHandlerTest.java b/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/InputsHandlerTest.java
new file mode 100644
index 0000000000000..8cfe1bae0b7c1
--- /dev/null
+++ b/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/InputsHandlerTest.java
@@ -0,0 +1,142 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.runtime.di;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import jakarta.json.Json;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonValue;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.talend.sdk.component.api.record.Record;
+import org.talend.sdk.component.api.service.record.RecordBuilderFactory;
+import org.talend.sdk.component.runtime.output.InputFactory;
+import org.talend.sdk.component.runtime.record.RecordBuilderFactoryImpl;
+
+class InputsHandlerTest {
+
+ private Jsonb jsonb;
+
+ private RecordBuilderFactory factory;
+
+ private InputsHandler handler;
+
+ @BeforeEach
+ void setUp() {
+ jsonb = JsonbBuilder.create();
+ factory = new RecordBuilderFactoryImpl("test");
+ final Map, Object> services = new HashMap<>();
+ services.put(RecordBuilderFactory.class, factory);
+ handler = new InputsHandler(jsonb, services);
+ }
+
+ @AfterEach
+ void tearDown() throws Exception {
+ jsonb.close();
+ }
+
+ @Test
+ void unknownOrEmptyConnectionReturnsNull() {
+ final InputFactory input = handler.asInputFactory();
+ assertNull(input.read("missing"));
+ handler.addConnection("FLOW", Object.class);
+ assertNull(input.read("FLOW"));
+ }
+
+ @Test
+ void recordIsPassedThrough() {
+ final Record rec = factory.newRecordBuilder().withString("name", "n").build();
+ handler.addConnection("FLOW", Record.class);
+ handler.setInputValue("FLOW", rec);
+ assertSame(rec, handler.asInputFactory().read("FLOW"));
+ }
+
+ @Test
+ void setInputValueOnUnknownConnectionIsIgnored() {
+ handler.setInputValue("nope", "value");
+ assertNull(handler.asInputFactory().read("nope"));
+ }
+
+ @Test
+ void initInputValueRegistersConnectionFromSimpleClassName() {
+ handler.initInputValue("FLOW", "x");
+ assertNull(handler.asInputFactory().read("FLOW"));
+ }
+
+ @Test
+ void jsonNullIsConvertedToNull() {
+ handler.addConnection("FLOW", JsonValue.class);
+ handler.setInputValue("FLOW", JsonValue.NULL);
+ assertNull(handler.asInputFactory().read("FLOW"));
+ }
+
+ @Test
+ void linearRowStructIsConvertedWithoutJsonb() {
+ final RowStruct row = new RowStruct();
+ row.name = "Alice";
+ handler.addConnection("FLOW", RowStruct.class);
+ handler.setInputValue("FLOW", row);
+ final Record rec = Record.class.cast(handler.asInputFactory().read("FLOW"));
+ assertNotNull(rec);
+ }
+
+ @Test
+ void nonLinearValueGoesThroughJsonbSerialization() {
+ // the legacy behaviour is preserved: the value is serialized then re-read as a json object,
+ // a json string can't be read as such so it fails the same way as before the refactoring
+ handler.addConnection("FLOW", JsonObject.class);
+ handler.setInputValue("FLOW", Json.createObjectBuilder().add("name", "Alice").build());
+ final InputFactory input = handler.asInputFactory();
+ assertThrows(ClassCastException.class, () -> input.read("FLOW"));
+
+ handler.addConnection("POJO", Pojo.class);
+ handler.setInputValue("POJO", new Pojo());
+ assertThrows(ClassCastException.class, () -> input.read("POJO"));
+ }
+
+ public static class RowStruct implements routines.system.IPersistableRow {
+
+ public String name;
+
+ @Override
+ public void writeData(final java.io.ObjectOutputStream out) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void readData(final java.io.ObjectInputStream in) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ public static class Pojo {
+
+ public String name;
+
+ public int age;
+ }
+}
diff --git a/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/beam/components/DIBatchSimulationTest.java b/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/beam/components/DIBatchSimulationTest.java
index 7f5d2f24225ab..f3c94eb949e2f 100644
--- a/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/beam/components/DIBatchSimulationTest.java
+++ b/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/beam/components/DIBatchSimulationTest.java
@@ -33,8 +33,8 @@
import java.util.stream.IntStream;
import java.util.stream.Stream;
-import javax.json.JsonObject;
-import javax.json.bind.Jsonb;
+import jakarta.json.JsonObject;
+import jakarta.json.bind.Jsonb;
import org.apache.beam.sdk.coders.SerializableCoder;
import org.apache.beam.sdk.transforms.Create;
@@ -243,7 +243,7 @@ private void doRun(final ComponentManager manager, final Collection sour
Object dataMapper;
while ((dataMapper = inputMapper.next()) != null) {
final String jsonValueMapper;
- if (dataMapper instanceof javax.json.JsonValue jsonValue) {
+ if (dataMapper instanceof jakarta.json.JsonValue jsonValue) {
jsonValueMapper = jsonValue.toString();
} else if (dataMapper instanceof org.talend.sdk.component.api.record.Record) {
jsonValueMapper = jsonbMapper
diff --git a/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/beam/components/DIBulkAutoChunkTest.java b/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/beam/components/DIBulkAutoChunkTest.java
index 62a4c3ac7daf0..861d11a7d4af9 100644
--- a/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/beam/components/DIBulkAutoChunkTest.java
+++ b/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/beam/components/DIBulkAutoChunkTest.java
@@ -37,7 +37,7 @@
import java.util.stream.IntStream;
import java.util.stream.Stream;
-import javax.json.bind.Jsonb;
+import jakarta.json.bind.Jsonb;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
diff --git a/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/beam/components/QueueMapperTest.java b/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/beam/components/QueueMapperTest.java
index 153c98c93c32b..987604812f3d0 100644
--- a/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/beam/components/QueueMapperTest.java
+++ b/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/beam/components/QueueMapperTest.java
@@ -20,7 +20,7 @@
import java.util.List;
-import javax.json.Json;
+import jakarta.json.Json;
import org.junit.jupiter.api.Test;
import org.talend.sdk.component.api.record.Record;
diff --git a/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/beam/components/QueueOutputTest.java b/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/beam/components/QueueOutputTest.java
index 2b98b46c14776..eacc952a33366 100644
--- a/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/beam/components/QueueOutputTest.java
+++ b/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/beam/components/QueueOutputTest.java
@@ -19,7 +19,7 @@
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
-import javax.json.Json;
+import jakarta.json.Json;
import org.junit.jupiter.api.Test;
import org.talend.sdk.component.api.record.Record;
diff --git a/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/schema/TaCoKitGuessSchemaTest.java b/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/schema/TaCoKitGuessSchemaTest.java
index 80de65bfb7dbb..b07fd74f93563 100644
--- a/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/schema/TaCoKitGuessSchemaTest.java
+++ b/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/schema/TaCoKitGuessSchemaTest.java
@@ -39,8 +39,8 @@
import java.util.regex.Pattern;
import java.util.stream.Stream;
-import javax.json.bind.Jsonb;
-import javax.json.bind.JsonbBuilder;
+import jakarta.json.bind.Jsonb;
+import jakarta.json.bind.JsonbBuilder;
import org.apache.beam.sdk.options.Description;
import org.junit.jupiter.api.Assertions;
diff --git a/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/schema/TypeConversionTest.java b/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/schema/TypeConversionTest.java
index f2722066b082f..1970029147fed 100644
--- a/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/schema/TypeConversionTest.java
+++ b/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/schema/TypeConversionTest.java
@@ -19,8 +19,8 @@
import java.math.BigDecimal;
-import javax.json.JsonValue;
-import javax.json.spi.JsonProvider;
+import jakarta.json.JsonValue;
+import jakarta.json.spi.JsonProvider;
import org.junit.jupiter.api.Test;
diff --git a/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/studio/DynamicColumnsTest.java b/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/studio/DynamicColumnsTest.java
index f16f1ee831fa0..610a0bfe08d96 100644
--- a/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/studio/DynamicColumnsTest.java
+++ b/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/studio/DynamicColumnsTest.java
@@ -41,7 +41,7 @@
import java.util.stream.IntStream;
import java.util.stream.Stream;
-import javax.json.bind.Jsonb;
+import jakarta.json.bind.Jsonb;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
diff --git a/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/studio/ProcessorBufferingTest.java b/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/studio/ProcessorBufferingTest.java
index 8f3d43c34f5eb..1b2000658c3e5 100644
--- a/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/studio/ProcessorBufferingTest.java
+++ b/component-studio/component-runtime-di/src/test/java/org/talend/sdk/component/runtime/di/studio/ProcessorBufferingTest.java
@@ -23,7 +23,7 @@
import java.util.Map;
import java.util.stream.Stream;
-import javax.json.bind.Jsonb;
+import jakarta.json.bind.Jsonb;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
diff --git a/component-tools-webapp/module-knowledge.md b/component-tools-webapp/module-knowledge.md
new file mode 100644
index 0000000000000..295cf1d5386cf
--- /dev/null
+++ b/component-tools-webapp/module-knowledge.md
@@ -0,0 +1,32 @@
+# Module Knowledge: component-tools-webapp
+
+## JAX-RS client gotchas
+
+### CXF's JAX-RS client does not auto-discover a JSON-B provider — register it explicitly
+
+[2026-09-23 | QTDI-3358] `jakarta.ws.rs.client.ClientBuilder.newClient().build()` on this repo's
+CXF 4.1.8 stack does **not** auto-discover a JSON-B `MessageBodyReader`/`MessageBodyWriter` for
+arbitrary `Map` (or POJO) payloads. Any client built this way and used to send/read
+JSON bodies fails at runtime with:
+
+```
+jakarta.ws.rs.ProcessingException: No message body writer has been found for class java.util.HashMap
+```
+
+**Fix**: register johnzon-jsonb's bundled provider explicitly on the client:
+
+```java
+client.register(org.apache.johnzon.jaxrs.jsonb.jaxrs.JsonbJaxrsProvider.class);
+```
+
+`JsonbJaxrsProvider` ships **inside** the `org.apache.johnzon:johnzon-jsonb` jar — no separate
+`johnzon-jaxrs` artifact is needed. If the class is imported directly (rather than relying on it
+arriving transitively, e.g. via `component-server`), add an explicit `johnzon-jsonb` dependency to
+this module's `pom.xml` rather than depending on a transitive path that could silently break.
+
+This was found while adding test coverage for `JakartaJAXRSClient#action` (previously untested) —
+the bug was real and pre-existing, not introduced by the test itself; reproduced first via the
+`ProcessingException` failing without the fix, then confirmed green after registering the provider.
+
+Applies to any future JAX-RS client built in this module (or elsewhere in the reactor) that
+constructs its own `Client` rather than reusing an already-provider-registered one.
diff --git a/component-tools-webapp/pom.xml b/component-tools-webapp/pom.xml
index 73dca379872b2..6da0ca1c3db77 100644
--- a/component-tools-webapp/pom.xml
+++ b/component-tools-webapp/pom.xml
@@ -41,6 +41,14 @@
component-server
${project.version}
+
+
+ org.apache.johnzon
+ johnzon-jsonb
+ ${johnzon.version}
+
org.talend.sdk.component
component-form-core
@@ -55,6 +63,7 @@
org.apache.openwebbeans
openwebbeans-se
+ ${owb.version}
provided
diff --git a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/AdminResource.java b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/AdminResource.java
index 3717b22d67106..82f8641c08fef 100644
--- a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/AdminResource.java
+++ b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/AdminResource.java
@@ -17,13 +17,13 @@
import static java.util.Optional.ofNullable;
-import javax.enterprise.context.ApplicationScoped;
-import javax.inject.Inject;
-import javax.ws.rs.HEAD;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Response;
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.HEAD;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.Response;
import org.talend.sdk.component.container.ContainerManager;
import org.talend.sdk.component.runtime.manager.ComponentFamilyMeta;
diff --git a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/FrontCompatibilityRouter.java b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/FrontCompatibilityRouter.java
index e3903462fc4f5..17cc433421182 100644
--- a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/FrontCompatibilityRouter.java
+++ b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/FrontCompatibilityRouter.java
@@ -17,8 +17,8 @@
import java.util.Set;
-import javax.servlet.ServletContainerInitializer;
-import javax.servlet.ServletContext;
+import jakarta.servlet.ServletContainerInitializer;
+import jakarta.servlet.ServletContext;
public class FrontCompatibilityRouter implements ServletContainerInitializer {
diff --git a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/JakartaJAXRSClient.java b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/JakartaJAXRSClient.java
new file mode 100644
index 0000000000000..ad978564f8fa2
--- /dev/null
+++ b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/JakartaJAXRSClient.java
@@ -0,0 +1,100 @@
+/**
+ * Copyright (C) 2006-2026 Talend Inc. - www.talend.com
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.talend.sdk.component.tools.webapp;
+
+import static jakarta.ws.rs.client.Entity.entity;
+import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE;
+import static java.util.stream.Collectors.toMap;
+
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.GenericType;
+
+import org.apache.johnzon.jaxrs.jsonb.jaxrs.JsonbJaxrsProvider;
+import org.talend.sdk.component.form.api.Client;
+
+/**
+ * jakarta.ws.rs based twin of {@link org.talend.sdk.component.form.internal.jaxrs.JAXRSClient}, kept local to this
+ * module since component-form-core stays on javax.ws.rs (it must remain usable by connectors, which are unaffected
+ * by the CXF 4.x/jakarta migration of component-server and this webapp).
+ */
+public class JakartaJAXRSClient implements Client {
+
+ private final jakarta.ws.rs.client.Client delegate;
+
+ private final WebTarget target;
+
+ private final boolean closeClient;
+
+ private final GenericType