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/component-api/pom.xml b/component-api/pom.xml index 24d1d9567de95..1909607479a65 100644 --- a/component-api/pom.xml +++ b/component-api/pom.xml @@ -52,6 +52,16 @@ johnzon-jsonb test + + + jakarta.json.bind + jakarta.json.bind-api + provided + 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..997f3fa52ecc6 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 @@ -69,9 +69,12 @@ public interface Schema { /** * @return All entries, including data and metadata, of this schema. */ + @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient Stream getAllEntries(); @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient default Map getEntryMap() { throw new UnsupportedOperationException("#getEntryMap is not implemented"); } @@ -91,6 +94,7 @@ default Schema.Builder toBuilder() { * @return all entries ordered */ @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient default List getEntriesOrdered() { return getEntriesOrdered(naturalOrder()); } @@ -103,6 +107,7 @@ default List getEntriesOrdered() { * @return all entries ordered with provided comparator */ @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient default List getEntriesOrdered(final Comparator comparator) { return getAllEntries().sorted(comparator).collect(Collectors.toList()); } @@ -211,6 +216,8 @@ interface Entry { /** * @return the raw name of this entry if exists, else return name. */ + @JsonbTransient + @jakarta.json.bind.annotation.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..4dbc29f0010dd 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 @@ -123,6 +123,7 @@ public String getRawName() { } @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient @Override public String getOriginalFieldName() { return null; diff --git a/component-runtime-beam/pom.xml b/component-runtime-beam/pom.xml index ce46be7870fa8..9043c0d2f8d06 100644 --- a/component-runtime-beam/pom.xml +++ b/component-runtime-beam/pom.xml @@ -42,6 +42,17 @@ + + + jakarta.json.bind + jakarta.json.bind-api + provided + org.talend.sdk.component component-runtime-manager 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..639c6aedcbe21 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 @@ -54,9 +54,11 @@ public class AvroRecord implements Record, AvroPropertyMapper, Unwrappable { private static final RecordConverters RECORD_CONVERTERS = new RecordConverters(); @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient private final IndexedRecord delegate; @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient private final AvroSchema schema; public AvroRecord(final IndexedRecord record) { 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..4749009826820 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 @@ -69,6 +69,7 @@ static AvroSchema toAvroSchema(final org.talend.sdk.component.api.record.Schema } @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient private final Schema delegate; private AvroSchema elementSchema; @@ -76,9 +77,11 @@ static AvroSchema toAvroSchema(final org.talend.sdk.component.api.record.Schema private List entries; @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient private Map entryMap; @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient private List metadataEntries; private Type type; @@ -173,12 +176,14 @@ public List getMetadata() { @Override @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient public Stream getAllEntries() { return Stream.concat(this.getEntries().stream(), this.getMetadata().stream()); } @Override @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient public Map getEntryMap() { synchronized (this) { if (entryMap == null || entryMap.isEmpty()) { @@ -193,6 +198,7 @@ public Map getEntryMap() { @Override @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient public EntriesOrder naturalOrder() { return EntriesOrder.of(getActualDelegate().getProp(ENTRIES_ORDER_PROP)); } diff --git a/component-runtime-impl/pom.xml b/component-runtime-impl/pom.xml index e5f975f289c89..e735647f6ea20 100644 --- a/component-runtime-impl/pom.xml +++ b/component-runtime-impl/pom.xml @@ -47,6 +47,17 @@ org.apache.johnzon johnzon-jsonb + + + jakarta.json.bind + jakarta.json.bind-api + provided + org.apache.logging.log4j log4j-slf4j-impl 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..5c3b1242eeee7 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 @@ -76,6 +76,7 @@ public final class RecordImpl implements Record { @Getter @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient private final Schema schema; private RecordImpl(final Map values, final Schema schema) { 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..297661514b132 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 @@ -53,16 +53,19 @@ public class SchemaImpl implements Schema { private final List entries; @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient private final List metadataEntries; @Getter private final Map props; @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient private final EntriesOrder entriesOrder; @Getter @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient private Map entryMap = new HashMap<>(); public static final String ENTRIES_ORDER_PROP = "talend.fields.order"; @@ -127,6 +130,7 @@ public List getMetadata() { @Override @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient public Stream getAllEntries() { return Stream.concat(this.metadataEntries.stream(), this.entries.stream()); } @@ -146,12 +150,14 @@ public Builder toBuilder() { @Override @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient public List getEntriesOrdered() { return getAllEntries().sorted(entriesOrder).collect(toList()); } @Override @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient public EntriesOrder naturalOrder() { return entriesOrder; } @@ -411,6 +417,7 @@ private EntryImpl(final EntryImpl.BuilderImpl builder) { @Override @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient public String getOriginalFieldName() { return rawName != null ? rawName : name; } 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..8efefb8bfd132 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 @@ -173,18 +173,21 @@ public List getMetadata() { @Override @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient public Stream getAllEntries() { return Stream.empty(); } @Override @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient public List getEntriesOrdered() { return emptyList(); } @Override @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient public Builder moveBefore(final String before, final String name) { throw new UnsupportedOperationException("#moveBefore()"); } @@ -251,6 +254,7 @@ public Builder remove(final Entry entry) { @Override @JsonbTransient + @jakarta.json.bind.annotation.JsonbTransient public List getEntriesOrdered(final Comparator comparator) { throw new UnsupportedOperationException("#getEntriesOrdered()"); } 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/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..1de462af03fcc 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 @@ -541,20 +541,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 javax.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 javax.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 javax.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/service/DefaultServiceProvider.java b/component-runtime-manager/src/main/java/org/talend/sdk/component/runtime/manager/service/DefaultServiceProvider.java index 04e18a1d72757..5940b924e987a 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 @@ -47,6 +47,7 @@ import javax.json.stream.JsonGeneratorFactory; import javax.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; @@ -229,14 +230,22 @@ private JsonbBuilder createPojoJsonbBuilder(final String id, final Supplier - 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..362acc8568df5 100644 --- a/component-server-parent/component-server/pom.xml +++ b/component-server-parent/component-server/pom.xml @@ -37,16 +37,39 @@ false + + + + + org.apache.johnzon + johnzon-core + ${johnzon-jakarta.version} + + + org.apache.johnzon + johnzon-mapper + ${johnzon-jakarta.version} + + + + 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 +101,24 @@ commons-cli ${commons-cli.version} - + org.apache.johnzon johnzon-jsonb + ${johnzon-jakarta.version} + + + + org.glassfish + javax.json + + + org.eclipse + yasson org.apache.commons @@ -104,8 +141,8 @@ provided - org.apache.geronimo.config - geronimo-config-impl + io.smallrye.config + smallrye-config org.apache.logging.log4j @@ -158,6 +195,20 @@ ${meecrowave.version} test + + org.mockito + mockito-junit-jupiter + test + + + + org.junit.jupiter + junit-jupiter-api + + + org.apache.tomee ziplock @@ -392,7 +443,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/META-INF/services/javax.json.spi.JsonProvider b/component-server-parent/component-server/src/main/resources/META-INF/services/javax.json.spi.JsonProvider new file mode 100644 index 0000000000000..52f1a6b2e4550 --- /dev/null +++ b/component-server-parent/component-server/src/main/resources/META-INF/services/javax.json.spi.JsonProvider @@ -0,0 +1 @@ +org.glassfish.json.JsonProviderImpl 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/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/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 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 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/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 cache = Caching.getCachingProvider().getCacheManager().getCache(cacheName); + final Object cached = cache == null ? null : cache.get(new GeneratedCacheKeyImpl(new Object[] { key })); + // CachePutInterceptor caches the whole CacheInvocationParameter wrapper (ported unchanged from + // upstream geronimo-jcache-simple), not the raw value - unwrap it for readable assertions. + return cached instanceof CacheInvocationParameter ? ((CacheInvocationParameter) cached).getValue() : cached; + } + + private InvocationContext mockContext(final Method method, final String key, final String value) { + final InvocationContext ic = mock(InvocationContext.class); + when(ic.getMethod()).thenReturn(method); + when(ic.getTarget()).thenReturn(target); + when(ic.getParameters()).thenReturn(new Object[] { key, value }); + return ic; + } + + private static class Target { + + @CachePut(cacheName = "cpi-beforeCache", afterInvocation = false) + void putBefore(@CacheKey final String id, @CacheValue final String value) { + // no-op + } + + @CachePut(cacheName = "cpi-afterCache", afterInvocation = true) + void putAfter(@CacheKey final String id, @CacheValue final String value) { + // no-op + } + + @CachePut(cacheName = "cpi-afterCacheForCache", afterInvocation = true, + cacheFor = IllegalStateException.class) + void putAfterCacheForIllegalState(@CacheKey final String id, @CacheValue final String value) { + // no-op + } + + @CachePut(cacheName = "cpi-checkedCache", afterInvocation = false) + void putThrowsChecked(@CacheKey final String id, @CacheValue final String value) throws IOException { + // no-op + } + + @CachePut(cacheName = "cpi-asyncCache", afterInvocation = false) + java.util.concurrent.CompletionStage putAsync(@CacheKey final String id, + @CacheValue final String value) { + return null; + } + } +} diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/cdi/CacheRemoveAllInterceptorTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/cdi/CacheRemoveAllInterceptorTest.java new file mode 100644 index 0000000000000..89a9b2f49dd34 --- /dev/null +++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/cdi/CacheRemoveAllInterceptorTest.java @@ -0,0 +1,224 @@ +/** + * 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.assertFalse; +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.IOException; +import java.lang.reflect.Method; +import java.util.concurrent.CompletableFuture; + +import javax.cache.Cache; +import javax.cache.CacheManager; +import javax.cache.Caching; +import javax.cache.annotation.CachePut; +import javax.cache.annotation.CacheRemoveAll; +import javax.cache.configuration.MutableConfiguration; + +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 CacheRemoveAllInterceptor} 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 CacheRemoveAllInterceptorTest { + + private CDIJCacheHelper helper; + + private CacheRemoveAllInterceptor 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 CacheRemoveAllInterceptor(helper); + target = new Target(); + } + + @Test + void beforeInvocationClearsBeforeTheMethodRuns() throws Throwable { + seed("crai-beforeCache", "k1", "v1"); + final Method method = Target.class.getDeclaredMethod("removeAllBefore"); + final InvocationContext ic = mockContext(method); + when(ic.proceed()).thenAnswer(invocation -> { + assertTrue(isEmpty("crai-beforeCache"), "afterInvocation=false must clear before proceed()"); + return null; + }); + + interceptor.cache(ic); + + assertTrue(isEmpty("crai-beforeCache")); + } + + @Test + void afterInvocationClearsOnlyAfterTheMethodSucceeds() throws Throwable { + seed("crai-afterCache", "k2", "v2"); + final Method method = Target.class.getDeclaredMethod("removeAllAfter"); + final InvocationContext ic = mockContext(method); + when(ic.proceed()).thenAnswer(invocation -> { + assertFalse(isEmpty("crai-afterCache"), "afterInvocation=true must not clear before proceed()"); + return null; + }); + + interceptor.cache(ic); + + assertTrue(isEmpty("crai-afterCache")); + } + + @Test + void readsItsOwnAfterInvocationFlagEvenWhenACoLocatedCachePutSaysOtherwise() throws Throwable { + // regression test for QTDI-3358 round 2 (commit ba099ea4579e): CacheRemoveAllInterceptor must + // read @CacheRemoveAll's OWN afterInvocation() flag, never a co-located @CachePut's flag. The + // target method below deliberately combines afterInvocation=false on @CacheRemoveAll with + // afterInvocation=true on the co-located @CachePut, so a regression back to reading the wrong + // annotation would flip this test's outcome. + seed("crai-mixedCache", "k3", "v3"); + final Method method = Target.class.getDeclaredMethod("removeAllBeforeWithCoLocatedAfterPut", String.class, + String.class); + final InvocationContext ic = mockContext(method, "id3", "value3"); + when(ic.proceed()).thenAnswer(invocation -> { + assertTrue(isEmpty("crai-mixedCache"), + "must honour @CacheRemoveAll(afterInvocation=false), not @CachePut(afterInvocation=true)"); + return null; + }); + + interceptor.cache(ic); + } + + @Test + void afterInvocationDoesNotClearWhenTheExceptionIsNotIncluded() throws Throwable { + seed("crai-evictForCache", "k4", "v4"); + final Method method = Target.class.getDeclaredMethod("removeAllAfterEvictForIllegalState"); + final InvocationContext ic = mockContext(method); + when(ic.proceed()).thenThrow(new IllegalArgumentException("not-included")); + + assertThrows(IllegalArgumentException.class, () -> interceptor.cache(ic)); + assertFalse(isEmpty("crai-evictForCache")); + } + + @Test + void afterInvocationClearsWhenTheExceptionIsIncluded() throws Throwable { + seed("crai-evictForCache2", "k5", "v5"); + final Method method = Target.class.getDeclaredMethod("removeAllAfterEvictForIllegalState2"); + final InvocationContext ic = mockContext(method); + when(ic.proceed()).thenThrow(new IllegalStateException("included")); + + assertThrows(IllegalStateException.class, () -> interceptor.cache(ic)); + assertTrue(isEmpty("crai-evictForCache2")); + } + + @Test + void synchronousCheckedExceptionPropagatesUnwrapped() throws Throwable { + final Method method = Target.class.getDeclaredMethod("removeAllThrowsChecked"); + final InvocationContext ic = mockContext(method); + 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 asyncFailureDoesNotPropagateToTheCaller() throws Throwable { + final Method method = Target.class.getDeclaredMethod("removeAllAsync"); + final InvocationContext ic = mockContext(method); + final CompletableFuture future = new CompletableFuture<>(); + when(ic.proceed()).thenReturn(future); + + final Object result = interceptor.cache(ic); + assertSame(future, result); + + future.completeExceptionally(new IOException("async-checked-failure")); + } + + private static void seed(final String cacheName, final String key, final String value) { + final CacheManager manager = Caching.getCachingProvider().getCacheManager(); + Cache cache = manager.getCache(cacheName); + if (cache == null) { + cache = manager.createCache(cacheName, new MutableConfiguration<>().setStoreByValue(false)); + } + cache.put(new GeneratedCacheKeyImpl(new Object[] { key }), value); + } + + private static boolean isEmpty(final String cacheName) { + final Cache cache = Caching.getCachingProvider().getCacheManager().getCache(cacheName); + return cache == null || !cache.iterator().hasNext(); + } + + private InvocationContext mockContext(final Method method, final Object... parameters) { + final InvocationContext ic = mock(InvocationContext.class); + when(ic.getMethod()).thenReturn(method); + when(ic.getTarget()).thenReturn(target); + when(ic.getParameters()).thenReturn(parameters); + return ic; + } + + private static class Target { + + @CacheRemoveAll(cacheName = "crai-beforeCache", afterInvocation = false) + void removeAllBefore() { + // no-op + } + + @CacheRemoveAll(cacheName = "crai-afterCache", afterInvocation = true) + void removeAllAfter() { + // no-op + } + + @CacheRemoveAll(cacheName = "crai-mixedCache", afterInvocation = false) + @CachePut(cacheName = "crai-mixedCache", afterInvocation = true) + void removeAllBeforeWithCoLocatedAfterPut(final String id, final String value) { + // no-op + } + + @CacheRemoveAll(cacheName = "crai-evictForCache", afterInvocation = true, + evictFor = IllegalStateException.class) + void removeAllAfterEvictForIllegalState() { + // no-op + } + + @CacheRemoveAll(cacheName = "crai-evictForCache2", afterInvocation = true, + evictFor = IllegalStateException.class) + void removeAllAfterEvictForIllegalState2() { + // no-op + } + + @CacheRemoveAll(cacheName = "crai-checkedCache", afterInvocation = false) + void removeAllThrowsChecked() throws IOException { + // no-op + } + + @CacheRemoveAll(cacheName = "crai-asyncCache", afterInvocation = false) + java.util.concurrent.CompletionStage removeAllAsync() { + return null; + } + } +} diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/cdi/CacheRemoveInterceptorTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/cdi/CacheRemoveInterceptorTest.java new file mode 100644 index 0000000000000..3e6e3217f7c3a --- /dev/null +++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/cdi/CacheRemoveInterceptorTest.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.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.io.IOException; +import java.lang.reflect.Method; +import java.util.concurrent.CompletableFuture; + +import javax.cache.Cache; +import javax.cache.CacheManager; +import javax.cache.Caching; +import javax.cache.annotation.CacheKey; +import javax.cache.annotation.CacheRemove; +import javax.cache.configuration.MutableConfiguration; + +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 CacheRemoveInterceptor} 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 CacheRemoveInterceptorTest { + + private CDIJCacheHelper helper; + + private CacheRemoveInterceptor 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 CacheRemoveInterceptor(helper); + target = new Target(); + } + + @Test + void beforeInvocationRemovesBeforeTheMethodRuns() throws Throwable { + seed("cri-beforeCache", "k1", "v1"); + final Method method = Target.class.getDeclaredMethod("removeBefore", String.class); + final InvocationContext ic = mockContext(method, "k1"); + when(ic.proceed()).thenAnswer(invocation -> { + assertNull(cachedValue("cri-beforeCache", "k1"), "afterInvocation=false must remove before proceed()"); + return null; + }); + + interceptor.cache(ic); + + assertNull(cachedValue("cri-beforeCache", "k1")); + } + + @Test + void afterInvocationRemovesOnlyAfterTheMethodSucceeds() throws Throwable { + seed("cri-afterCache", "k2", "v2"); + final Method method = Target.class.getDeclaredMethod("removeAfter", String.class); + final InvocationContext ic = mockContext(method, "k2"); + when(ic.proceed()).thenAnswer(invocation -> { + assertEquals("v2", cachedValue("cri-afterCache", "k2"), + "afterInvocation=true must not remove before proceed()"); + return null; + }); + + interceptor.cache(ic); + + assertNull(cachedValue("cri-afterCache", "k2")); + } + + @Test + void afterInvocationDoesNotRemoveWhenTheExceptionIsNotIncluded() throws Throwable { + seed("cri-evictForCache", "k3", "v3"); + final Method method = Target.class.getDeclaredMethod("removeAfterEvictForIllegalState", String.class); + final InvocationContext ic = mockContext(method, "k3"); + when(ic.proceed()).thenThrow(new IllegalArgumentException("not-included")); + + assertThrows(IllegalArgumentException.class, () -> interceptor.cache(ic)); + assertEquals("v3", cachedValue("cri-evictForCache", "k3")); + } + + @Test + void afterInvocationRemovesWhenTheExceptionIsIncluded() throws Throwable { + seed("cri-evictForCache", "k4", "v4"); + final Method method = Target.class.getDeclaredMethod("removeAfterEvictForIllegalState", String.class); + final InvocationContext ic = mockContext(method, "k4"); + when(ic.proceed()).thenThrow(new IllegalStateException("included")); + + assertThrows(IllegalStateException.class, () -> interceptor.cache(ic)); + assertNull(cachedValue("cri-evictForCache", "k4")); + } + + @Test + void synchronousCheckedExceptionPropagatesUnwrapped() throws Throwable { + final Method method = Target.class.getDeclaredMethod("removeThrowsChecked", String.class); + final InvocationContext ic = mockContext(method, "k5"); + 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 asyncFailureDoesNotPropagateToTheCaller() throws Throwable { + seed("cri-asyncCache", "k6", "v6"); + final Method method = Target.class.getDeclaredMethod("removeAsync", String.class); + final InvocationContext ic = mockContext(method, "k6"); + final CompletableFuture future = new CompletableFuture<>(); + when(ic.proceed()).thenReturn(future); + + final Object result = interceptor.cache(ic); + assertSame(future, result); + + future.completeExceptionally(new IOException("async-checked-failure")); + } + + private static void seed(final String cacheName, final String key, final String value) { + final CacheManager manager = Caching.getCachingProvider().getCacheManager(); + Cache cache = manager.getCache(cacheName); + if (cache == null) { + cache = manager.createCache(cacheName, new MutableConfiguration<>().setStoreByValue(false)); + } + cache.put(new GeneratedCacheKeyImpl(new Object[] { key }), value); + assertNotNull(cachedValue(cacheName, key), "seeding must be visible before the interceptor runs"); + } + + private static Object cachedValue(final String cacheName, final Object key) { + final Cache cache = Caching.getCachingProvider().getCacheManager().getCache(cacheName); + return cache == null ? null : cache.get(new GeneratedCacheKeyImpl(new Object[] { key })); + } + + private InvocationContext mockContext(final Method method, final String key) { + final InvocationContext ic = mock(InvocationContext.class); + when(ic.getMethod()).thenReturn(method); + when(ic.getTarget()).thenReturn(target); + when(ic.getParameters()).thenReturn(new Object[] { key }); + return ic; + } + + private static class Target { + + @CacheRemove(cacheName = "cri-beforeCache", afterInvocation = false) + void removeBefore(@CacheKey final String id) { + // no-op + } + + @CacheRemove(cacheName = "cri-afterCache", afterInvocation = true) + void removeAfter(@CacheKey final String id) { + // no-op + } + + @CacheRemove(cacheName = "cri-evictForCache", afterInvocation = true, + evictFor = IllegalStateException.class) + void removeAfterEvictForIllegalState(@CacheKey final String id) { + // no-op + } + + @CacheRemove(cacheName = "cri-checkedCache", afterInvocation = false) + void removeThrowsChecked(@CacheKey final String id) throws IOException { + // no-op + } + + @CacheRemove(cacheName = "cri-asyncCache", afterInvocation = false) + java.util.concurrent.CompletionStage removeAsync(@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/CacheResultInterceptorTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/cdi/CacheResultInterceptorTest.java new file mode 100644 index 0000000000000..87e2f0d2b683c --- /dev/null +++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/service/jcache/cdi/CacheResultInterceptorTest.java @@ -0,0 +1,206 @@ +/** + * 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.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.lang.reflect.Method; +import java.util.concurrent.CompletableFuture; + +import javax.cache.annotation.CacheKey; +import javax.cache.annotation.CacheResult; + +import jakarta.enterprise.inject.spi.BeanManager; +import jakarta.interceptor.InvocationContext; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +/** + * Exercises {@link CacheResultInterceptor} 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 CacheResultInterceptorTest { + + private CDIJCacheHelper helper; + + private CacheResultInterceptor 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 CacheResultInterceptor(helper); + target = new Target(); + } + + @Test + void cacheMissInvokesMethodAndCachesResult() throws Throwable { + final Method method = Target.class.getDeclaredMethod("load", String.class); + final InvocationContext ic = mockContext(method, "k1"); + when(ic.proceed()).thenReturn("computed-1"); + + final Object first = interceptor.cache(ic); + assertEquals("computed-1", first); + verify(ic, times(1)).proceed(); + } + + @Test + void cacheHitSkipsSecondInvocation() throws Throwable { + final Method method = Target.class.getDeclaredMethod("load", String.class); + final InvocationContext ic1 = mockContext(method, "k2"); + when(ic1.proceed()).thenReturn("computed-2"); + interceptor.cache(ic1); + + final InvocationContext ic2 = mockContext(method, "k2"); + final Object second = interceptor.cache(ic2); + + assertEquals("computed-2", second); + verify(ic2, never()).proceed(); + } + + @Test + void differentKeysAreCachedIndependently() throws Throwable { + final Method method = Target.class.getDeclaredMethod("load", String.class); + final InvocationContext icA = mockContext(method, "a"); + when(icA.proceed()).thenReturn("value-a"); + interceptor.cache(icA); + + final InvocationContext icB = mockContext(method, "b"); + when(icB.proceed()).thenReturn("value-b"); + final Object result = interceptor.cache(icB); + + assertEquals("value-b", result); + verify(icB, times(1)).proceed(); + } + + @Test + void skipGetAlwaysInvokesTheMethodEvenWhenAlreadyCached() throws Throwable { + final Method method = Target.class.getDeclaredMethod("loadSkipGet", String.class); + final InvocationContext ic1 = mockContext(method, "k3"); + when(ic1.proceed()).thenReturn("first"); + interceptor.cache(ic1); + + final InvocationContext ic2 = mockContext(method, "k3"); + when(ic2.proceed()).thenReturn("second"); + final Object result = interceptor.cache(ic2); + + assertEquals("second", result); + verify(ic2, times(1)).proceed(); + } + + @Test + void includedExceptionIsCachedAndReplayedWithoutReInvokingTheMethod() throws Throwable { + final Method method = Target.class.getDeclaredMethod("loadCachingExceptions", String.class); + final InvocationContext ic1 = mockContext(method, "k4"); + final IllegalStateException failure = new IllegalStateException("boom"); + when(ic1.proceed()).thenThrow(failure); + + final Throwable firstThrown = assertThrows(IllegalStateException.class, () -> interceptor.cache(ic1)); + assertSame(failure, firstThrown); + + final InvocationContext ic2 = mockContext(method, "k4"); + final Throwable secondThrown = assertThrows(Throwable.class, () -> interceptor.cache(ic2)); + + assertSame(failure, secondThrown); + verify(ic2, never()).proceed(); + } + + @Test + void nonIncludedExceptionIsNotCachedAndTheMethodIsReInvoked() throws Throwable { + final Method method = Target.class.getDeclaredMethod("loadNotCachingExceptions", String.class); + final InvocationContext ic1 = mockContext(method, "k5"); + when(ic1.proceed()).thenThrow(new IllegalArgumentException("first-failure")); + assertThrows(IllegalArgumentException.class, () -> interceptor.cache(ic1)); + + final InvocationContext ic2 = mockContext(method, "k5"); + when(ic2.proceed()).thenThrow(new IllegalArgumentException("second-failure")); + assertThrows(IllegalArgumentException.class, () -> interceptor.cache(ic2)); + + verify(ic2, times(1)).proceed(); + } + + @Test + void asyncResultIsCachedAndFailureCallbackDoesNotPropagate() throws Throwable { + final Method method = Target.class.getDeclaredMethod("loadAsync", String.class); + final InvocationContext ic = mockContext(method, "k6"); + final CompletableFuture future = new CompletableFuture<>(); + when(ic.proceed()).thenReturn(future); + + final Object result = interceptor.cache(ic); + assertSame(future, result); + + // completing exceptionally must not throw back to the caller - onAsyncFailure runs as a + // dependent stage action and its own (re-)throw is captured by the CompletionStage machinery. + future.completeExceptionally(new IllegalStateException("async-boom")); + + final InvocationContext ic2 = mockContext(method, "k6"); + final Object second = interceptor.cache(ic2); + assertSame(future, second, "the failed stage remains the cached value for this key"); + verify(ic2, never()).proceed(); + } + + private InvocationContext mockContext(final Method method, final String key) { + final InvocationContext ic = mock(InvocationContext.class); + when(ic.getMethod()).thenReturn(method); + when(ic.getTarget()).thenReturn(target); + when(ic.getParameters()).thenReturn(new Object[] { key }); + return ic; + } + + private static class Target { + + @CacheResult(cacheName = "cri-resultCache") + String load(@CacheKey final String id) { + return null; + } + + @CacheResult(cacheName = "cri-skipGetCache", skipGet = true) + String loadSkipGet(@CacheKey final String id) { + return null; + } + + @CacheResult(cacheName = "cri-excCache", exceptionCacheName = "cri-excCache-ex", + cachedExceptions = IllegalStateException.class) + String loadCachingExceptions(@CacheKey final String id) { + return null; + } + + @CacheResult(cacheName = "cri-notCachedExcCache", exceptionCacheName = "cri-notCachedExcCache-ex", + nonCachedExceptions = IllegalArgumentException.class) + String loadNotCachingExceptions(@CacheKey final String id) { + return null; + } + + @CacheResult(cacheName = "cri-asyncCache", exceptionCacheName = "cri-asyncCache-ex", + cachedExceptions = IllegalStateException.class) + java.util.concurrent.CompletionStage loadAsync(@CacheKey final String id) { + return null; + } + } +} diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/ClientProducer.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/ClientProducer.java index 52bb8ee158095..f5fd84d42337b 100644 --- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/ClientProducer.java +++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/ClientProducer.java @@ -15,12 +15,12 @@ */ package org.talend.sdk.component.server.test; -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.inject.Disposes; -import javax.enterprise.inject.Produces; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.WebTarget; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.inject.Disposes; +import jakarta.enterprise.inject.Produces; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.WebTarget; import org.apache.cxf.Bus; import org.apache.cxf.endpoint.Server; diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/ComponentClient.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/ComponentClient.java index cffa079d04301..c7666a75d3cdf 100644 --- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/ComponentClient.java +++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/ComponentClient.java @@ -15,11 +15,11 @@ */ package org.talend.sdk.component.server.test; -import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; +import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; -import javax.ws.rs.client.WebTarget; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.client.WebTarget; import org.talend.sdk.component.server.front.model.ComponentIndices; import org.talend.sdk.component.server.front.model.ConfigTypeNodes; diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/InitTestInfra.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/InitTestInfra.java index c7b0be2e5ed8d..cfd3b7645d9f1 100644 --- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/InitTestInfra.java +++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/InitTestInfra.java @@ -50,7 +50,7 @@ import java.util.stream.Stream; import java.util.zip.ZipEntry; -import javax.json.bind.config.PropertyOrderStrategy; +import jakarta.json.bind.config.PropertyOrderStrategy; import org.apache.meecrowave.Meecrowave; import org.apache.meecrowave.configuration.Configuration; diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/file/FileWriter.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/file/FileWriter.java index 9ecd44e8340ed..7b0ee6b0dbfd1 100644 --- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/file/FileWriter.java +++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/file/FileWriter.java @@ -20,8 +20,8 @@ import java.io.IOException; 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.processor.AfterGroup; diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/jdbc/JdbcInput.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/jdbc/JdbcInput.java index 301fc42d30290..1328a22ec97bf 100644 --- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/jdbc/JdbcInput.java +++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/jdbc/JdbcInput.java @@ -29,8 +29,8 @@ import java.util.Map; import java.util.function.Supplier; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import org.talend.sdk.component.api.component.DatabaseMapping; import org.talend.sdk.component.api.component.Icon; diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/jdbc/JdbcOutput.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/jdbc/JdbcOutput.java index 2af3e73c55cbc..4b0d7b9b4347b 100644 --- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/jdbc/JdbcOutput.java +++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/jdbc/JdbcOutput.java @@ -17,7 +17,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.configuration.Option; diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/model/FileOutput.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/model/FileOutput.java index d6b7055a5c336..2283b487c8c61 100644 --- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/model/FileOutput.java +++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/model/FileOutput.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.component.Icon; import org.talend.sdk.component.api.configuration.Option; diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/model/InfiniteMapper.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/model/InfiniteMapper.java index c0de05f791088..cf43b5600d11e 100644 --- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/model/InfiniteMapper.java +++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/model/InfiniteMapper.java @@ -19,7 +19,7 @@ import java.util.List; -import javax.json.JsonObject; +import jakarta.json.JsonObject; import org.talend.sdk.component.api.configuration.Option; import org.talend.sdk.component.api.input.Assessor; diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/model/InfiniteStoppableMapper.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/model/InfiniteStoppableMapper.java index e3f7416e64840..fca4a4e47201b 100644 --- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/model/InfiniteStoppableMapper.java +++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/model/InfiniteStoppableMapper.java @@ -19,7 +19,7 @@ import java.util.List; -import javax.json.JsonObject; +import jakarta.json.JsonObject; import org.talend.sdk.component.api.configuration.Option; import org.talend.sdk.component.api.input.Assessor; diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/vault/TenantHeaderFilter.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/vault/TenantHeaderFilter.java index 042f6477ed358..766ec234024cd 100644 --- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/vault/TenantHeaderFilter.java +++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/vault/TenantHeaderFilter.java @@ -15,10 +15,10 @@ */ package org.talend.sdk.component.server.test.vault; -import javax.enterprise.context.Dependent; -import javax.ws.rs.container.ContainerRequestContext; -import javax.ws.rs.container.ContainerRequestFilter; -import javax.ws.rs.ext.Provider; +import jakarta.enterprise.context.Dependent; +import jakarta.ws.rs.container.ContainerRequestContext; +import jakarta.ws.rs.container.ContainerRequestFilter; +import jakarta.ws.rs.ext.Provider; @Dependent @Provider diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/vault/VaultMock.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/vault/VaultMock.java index 8aa6417b3d21e..aa6ebdb4d1e1c 100644 --- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/vault/VaultMock.java +++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/vault/VaultMock.java @@ -20,17 +20,17 @@ import java.nio.charset.StandardCharsets; import java.util.Base64; -import javax.enterprise.context.ApplicationScoped; -import javax.ws.rs.Consumes; -import javax.ws.rs.ForbiddenException; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.ForbiddenException; +import jakarta.ws.rs.HeaderParam; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; import org.talend.sdk.components.vault.client.VaultClient; diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/websocket/WebsocketClient.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/websocket/WebsocketClient.java index 464378d8b7a3e..810d64da91f29 100644 --- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/websocket/WebsocketClient.java +++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/test/websocket/WebsocketClient.java @@ -27,20 +27,20 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicReference; -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; -import javax.json.bind.Jsonb; -import javax.json.bind.spi.JsonbProvider; -import javax.websocket.ClientEndpointConfig; -import javax.websocket.CloseReason; -import javax.websocket.ContainerProvider; -import javax.websocket.DeploymentException; -import javax.websocket.Endpoint; -import javax.websocket.EndpointConfig; -import javax.websocket.MessageHandler; -import javax.websocket.RemoteEndpoint; -import javax.websocket.Session; -import javax.websocket.WebSocketContainer; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.json.bind.Jsonb; +import jakarta.json.bind.spi.JsonbProvider; +import jakarta.websocket.ClientEndpointConfig; +import jakarta.websocket.CloseReason; +import jakarta.websocket.ContainerProvider; +import jakarta.websocket.DeploymentException; +import jakarta.websocket.Endpoint; +import jakarta.websocket.EndpointConfig; +import jakarta.websocket.MessageHandler; +import jakarta.websocket.RemoteEndpoint; +import jakarta.websocket.Session; +import jakarta.websocket.WebSocketContainer; import org.apache.meecrowave.Meecrowave; diff --git a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/tomcat/TomcatSetupTest.java b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/tomcat/TomcatSetupTest.java index 021c9e925e1f6..28839ca1eb38e 100644 --- a/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/tomcat/TomcatSetupTest.java +++ b/component-server-parent/component-server/src/test/java/org/talend/sdk/component/server/tomcat/TomcatSetupTest.java @@ -18,14 +18,16 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import javax.inject.Inject; -import javax.ws.rs.client.Client; +import jakarta.inject.Inject; +import jakarta.ws.rs.client.Client; import org.apache.meecrowave.Meecrowave; -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 TomcatSetupTest { @Inject diff --git a/component-server-parent/extensions/component-server-extension-api/pom.xml b/component-server-parent/extensions/component-server-extension-api/pom.xml index 718c43991e788..5a6f4750ab3ec 100644 --- a/component-server-parent/extensions/component-server-extension-api/pom.xml +++ b/component-server-parent/extensions/component-server-extension-api/pom.xml @@ -38,14 +38,12 @@ ${project.version} - 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..c41e9a6d826d0 100644 --- a/component-starter-server/pom.xml +++ b/component-starter-server/pom.xml @@ -36,9 +36,22 @@ - + org.apache.johnzon johnzon-jsonb + ${johnzon-jakarta.version} + + + + org.apache.johnzon + johnzon-core + ${johnzon-jakarta.version} org.apache.meecrowave @@ -79,8 +92,8 @@ microprofile-config-api - org.apache.geronimo.config - geronimo-config-impl + io.smallrye.config + smallrye-config org.apache.logging.log4j @@ -262,7 +275,7 @@ org.apache.johnzon johnzon-jsonb - ${johnzon.version} + ${johnzon-jakarta.version} 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/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-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..f7aa46dc526ab 100644 --- a/component-tools-webapp/pom.xml +++ b/component-tools-webapp/pom.xml @@ -35,12 +35,45 @@ ${talend.build.name.base}.tools.webapp + + + + + org.apache.johnzon + johnzon-core + ${johnzon-jakarta.version} + + + org.apache.johnzon + johnzon-mapper + ${johnzon-jakarta.version} + + + org.apache.johnzon + johnzon-jsonb + ${johnzon-jakarta.version} + + + + org.talend.sdk.component component-server ${project.version} + + + org.apache.johnzon + johnzon-jsonb + ${johnzon-jakarta.version} + org.talend.sdk.component component-form-core @@ -55,6 +88,7 @@ org.apache.openwebbeans openwebbeans-se + ${owb.version} provided @@ -101,7 +135,7 @@ org.apache.johnzon johnzon-jsonb - ${johnzon.version} + ${johnzon-jakarta.version} org.apache.logging.log4j 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> mapType; + + public JakartaJAXRSClient(final String base) { + this(newClient(), base, true); + } + + public JakartaJAXRSClient(final jakarta.ws.rs.client.Client client, final String base, + final boolean closeClient) { + this.delegate = client; + this.closeClient = closeClient; + // CXF's JAX-RS client does not auto-discover a JSON-B MessageBodyReader/Writer for plain + // Map payloads - register johnzon-jsonb's provider explicitly, otherwise both the + // request payload conversion and the response mapping in #action fail at runtime. + client.register(JsonbJaxrsProvider.class); + this.target = client.target(base); + this.mapType = new GenericType>() { + }; + } + + @Override + public CompletableFuture> action(final String family, final String type, final String action, + final String lang, final Map params, final T context) { + final Map payload = + params.entrySet().stream().collect(toMap(Map.Entry::getKey, e -> String.valueOf(e.getValue()))); + return target + .path("action/execute") + .queryParam("family", family) + .queryParam("type", type) + .queryParam("action", action) + .queryParam("lang", lang) + .request(APPLICATION_JSON_TYPE) + .rx() + .post(entity(payload, APPLICATION_JSON_TYPE), mapType) + .toCompletableFuture(); + } + + @Override + public void close() { + if (closeClient) { + delegate.close(); + } + } + + private static jakarta.ws.rs.client.Client newClient() { + final jakarta.ws.rs.client.Client instance = ClientBuilder.newClient(); + System + .getProperties() + .stringPropertyNames() + .stream() + .filter(k -> k.startsWith("talend.component.form.client.jaxrs.properties.")) + .forEach(k -> instance + .property(k.substring("talend.component.form.client.jaxrs.properties.".length()), + System.getProperty(k))); + return instance; + } +} diff --git a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/LazyClient.java b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/LazyClient.java index 83e216e658a4e..16b1da17f6858 100644 --- a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/LazyClient.java +++ b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/LazyClient.java @@ -24,23 +24,22 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; -import javax.annotation.PreDestroy; -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.context.Dependent; -import javax.enterprise.inject.Produces; -import javax.inject.Inject; -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.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.WebTarget; +import jakarta.annotation.PreDestroy; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.context.Dependent; +import jakarta.enterprise.inject.Produces; +import jakarta.inject.Inject; +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.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.WebTarget; import org.talend.sdk.component.form.api.Client; -import org.talend.sdk.component.form.internal.jaxrs.JAXRSClient; import lombok.experimental.Delegate; @@ -74,10 +73,10 @@ public Thread newThread(final Runnable r) { return thread; } }); - final javax.ws.rs.client.Client jaxrsClient = + final jakarta.ws.rs.client.Client jaxrsClient = ClientBuilder.newBuilder().property("executorService", executorService).build(); webTarget = jaxrsClient.target(baseValue); - client = new JAXRSClient<>(jaxrsClient, baseValue, true); + client = new JakartaJAXRSClient<>(jaxrsClient, baseValue, true); } } } diff --git a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/ResourceProxy.java b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/ResourceProxy.java index 9709e11151ef8..9cff4ef37e80e 100644 --- a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/ResourceProxy.java +++ b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/ResourceProxy.java @@ -21,15 +21,15 @@ import java.net.URL; import java.nio.charset.StandardCharsets; -import javax.enterprise.context.Dependent; -import javax.inject.Inject; -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 jakarta.enterprise.context.Dependent; +import jakarta.inject.Inject; +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; @Dependent @WebFilter(urlPatterns = "/*", asyncSupported = true, filterName = "ResourceProxy") diff --git a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/UIConfiguration.java b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/UIConfiguration.java index db2a239fa4f47..6ad36ed70a40f 100644 --- a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/UIConfiguration.java +++ b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/UIConfiguration.java @@ -17,8 +17,8 @@ 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-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/WebAppComponentProxy.java b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/WebAppComponentProxy.java index c6e7c67fb969c..aa10a9eaa5849 100644 --- a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/WebAppComponentProxy.java +++ b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/WebAppComponentProxy.java @@ -15,9 +15,9 @@ */ package org.talend.sdk.component.tools.webapp; +import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; import static java.util.Collections.emptyMap; import static java.util.Optional.ofNullable; -import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; import java.nio.charset.StandardCharsets; import java.util.Base64; @@ -25,21 +25,21 @@ import java.util.Map; import java.util.concurrent.CompletionException; -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; -import javax.servlet.http.HttpServletRequest; -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.QueryParam; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.container.AsyncResponse; -import javax.ws.rs.container.Suspended; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.Response; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.servlet.http.HttpServletRequest; +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.QueryParam; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.client.WebTarget; +import jakarta.ws.rs.container.AsyncResponse; +import jakarta.ws.rs.container.Suspended; +import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.Response; import org.talend.sdk.component.form.api.ActionService; import org.talend.sdk.component.form.api.Client; diff --git a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/WebAppConfiguration.java b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/WebAppConfiguration.java index f665380cbbf11..447d60660def2 100644 --- a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/WebAppConfiguration.java +++ b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/WebAppConfiguration.java @@ -15,9 +15,9 @@ */ package org.talend.sdk.component.tools.webapp; -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.inject.Disposes; -import javax.enterprise.inject.Produces; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.inject.Disposes; +import jakarta.enterprise.inject.Produces; import org.talend.sdk.component.form.api.ActionService; import org.talend.sdk.component.form.api.Client; diff --git a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/standalone/generator/StaticResourceGenerator.java b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/standalone/generator/StaticResourceGenerator.java index 32de35b98fdc7..64a37d2a868e6 100644 --- a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/standalone/generator/StaticResourceGenerator.java +++ b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/standalone/generator/StaticResourceGenerator.java @@ -41,17 +41,17 @@ import java.util.function.Supplier; import java.util.stream.Stream; -import javax.enterprise.inject.se.SeContainer; -import javax.enterprise.inject.se.SeContainerInitializer; -import javax.json.bind.Jsonb; -import javax.json.bind.JsonbBuilder; -import javax.json.bind.JsonbConfig; -import javax.json.bind.config.BinaryDataStrategy; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.StreamingOutput; +import jakarta.enterprise.inject.se.SeContainer; +import jakarta.enterprise.inject.se.SeContainerInitializer; +import jakarta.json.bind.Jsonb; +import jakarta.json.bind.JsonbBuilder; +import jakarta.json.bind.JsonbConfig; +import jakarta.json.bind.config.BinaryDataStrategy; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.HttpHeaders; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.StreamingOutput; import org.talend.sdk.component.path.PathFactory; import org.talend.sdk.component.server.api.ActionResource; diff --git a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/standalone/generator/StaticUiSpecGenerator.java b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/standalone/generator/StaticUiSpecGenerator.java index 2fc76d787b271..a53241c6b2a87 100644 --- a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/standalone/generator/StaticUiSpecGenerator.java +++ b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/standalone/generator/StaticUiSpecGenerator.java @@ -37,8 +37,8 @@ import java.util.jar.JarOutputStream; 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.talend.sdk.component.form.api.Client; import org.talend.sdk.component.form.api.UiSpecService; diff --git a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/standalone/main/ActionExecutor.java b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/standalone/main/ActionExecutor.java index 1f0e749e38653..67a04cc7893b2 100644 --- a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/standalone/main/ActionExecutor.java +++ b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/standalone/main/ActionExecutor.java @@ -26,8 +26,8 @@ import java.util.Objects; import java.util.Properties; -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.container.Container; import org.talend.sdk.component.runtime.manager.ComponentManager; diff --git a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/standalone/servlet/StaticResourceServlet.java b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/standalone/servlet/StaticResourceServlet.java index e3f11d45e8958..56bd97d13f77a 100644 --- a/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/standalone/servlet/StaticResourceServlet.java +++ b/component-tools-webapp/src/main/java/org/talend/sdk/component/tools/webapp/standalone/servlet/StaticResourceServlet.java @@ -35,14 +35,14 @@ import java.util.function.Supplier; 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.BinaryDataStrategy; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; +import jakarta.json.bind.Jsonb; +import jakarta.json.bind.JsonbBuilder; +import jakarta.json.bind.JsonbConfig; +import jakarta.json.bind.config.BinaryDataStrategy; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.talend.sdk.component.path.PathFactory; import org.talend.sdk.component.tools.webapp.standalone.Route; diff --git a/component-tools-webapp/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer b/component-tools-webapp/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer similarity index 100% rename from component-tools-webapp/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer rename to component-tools-webapp/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer diff --git a/component-tools-webapp/src/test/java/org/talend/sdk/component/tools/webapp/JakartaJAXRSClientTest.java b/component-tools-webapp/src/test/java/org/talend/sdk/component/tools/webapp/JakartaJAXRSClientTest.java new file mode 100644 index 0000000000000..d08c3ebdd279f --- /dev/null +++ b/component-tools-webapp/src/test/java/org/talend/sdk/component/tools/webapp/JakartaJAXRSClientTest.java @@ -0,0 +1,140 @@ +/** + * 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 org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpServer; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class JakartaJAXRSClientTest { + + private HttpServer server; + + private volatile String capturedMethod; + + private volatile String capturedPath; + + private volatile String capturedQuery; + + private volatile String capturedContentType; + + private volatile String capturedBody; + + @BeforeEach + void startServer() throws IOException { + server = HttpServer.create(new InetSocketAddress("localhost", 0), 0); + server.createContext("/action/execute", this::handle); + server.start(); + } + + @AfterEach + void stopServer() { + server.stop(0); + } + + private void handle(final HttpExchange exchange) throws IOException { + capturedMethod = exchange.getRequestMethod(); + capturedPath = exchange.getRequestURI().getPath(); + capturedQuery = exchange.getRequestURI().getQuery(); + capturedContentType = exchange.getRequestHeaders().getFirst("Content-Type"); + try (final InputStream in = exchange.getRequestBody(); + final ByteArrayOutputStream out = + new ByteArrayOutputStream()) { + final byte[] buffer = new byte[4096]; + int read; + while ((read = in.read(buffer)) >= 0) { + out.write(buffer, 0, read); + } + capturedBody = new String(out.toByteArray(), StandardCharsets.UTF_8); + } + final byte[] response = "{\"status\":\"ok\"}".getBytes(StandardCharsets.UTF_8); + exchange.getResponseHeaders().add("Content-Type", "application/json"); + exchange.sendResponseHeaders(200, response.length); + try (final OutputStream body = exchange.getResponseBody()) { + body.write(response); + } + } + + private String baseUrl() { + return "http://localhost:" + server.getAddress().getPort() + "/"; + } + + @Test + void actionSendsRequestAndMapsResponse() throws Exception { + final Map params = new LinkedHashMap<>(); + params.put("aString", "value"); + params.put("aNumber", 42); + try (final JakartaJAXRSClient client = new JakartaJAXRSClient<>(baseUrl())) { + final Map result = + client.action("myFamily", "myType", "myAction", "en", params, null) + .toCompletableFuture() + .get(10, TimeUnit.SECONDS); + + assertEquals("POST", capturedMethod); + assertEquals("/action/execute", capturedPath); + assertTrue(capturedQuery.contains("family=myFamily")); + assertTrue(capturedQuery.contains("type=myType")); + assertTrue(capturedQuery.contains("action=myAction")); + assertTrue(capturedQuery.contains("lang=en")); + assertTrue(capturedContentType.startsWith("application/json")); + // payload conversion: every param value is stringified before being sent, incl. numbers + assertTrue(capturedBody.contains("\"aString\":\"value\"")); + assertTrue(capturedBody.contains("\"aNumber\":\"42\"")); + + assertEquals(Map.of("status", "ok"), result); + } + } + + @Test + void closeDelegatesToUnderlyingClientOnlyWhenOwned() { + try (final jakarta.ws.rs.client.Client delegate = jakarta.ws.rs.client.ClientBuilder.newClient()) { + // closeClient=false: this instance does not own the delegate, close() must be a no-op on it + final JakartaJAXRSClient nonOwning = new JakartaJAXRSClient<>(delegate, baseUrl(), false); + nonOwning.close(); + // the delegate is still usable after a non-owning close() + assertNull(probeDelegateClosed(delegate)); + } + } + + /** + * @return null if the delegate is still open (probing it does not throw), otherwise the thrown exception. + */ + private Exception probeDelegateClosed(final jakarta.ws.rs.client.Client delegate) { + try { + delegate.target(baseUrl()); + return null; + } catch (final IllegalStateException e) { + return e; + } + } +} diff --git a/component-tools/src/main/java/org/talend/sdk/component/tools/WebServer.java b/component-tools/src/main/java/org/talend/sdk/component/tools/WebServer.java index 9512c536b3735..c18de202b2f8b 100644 --- a/component-tools/src/main/java/org/talend/sdk/component/tools/WebServer.java +++ b/component-tools/src/main/java/org/talend/sdk/component/tools/WebServer.java @@ -167,7 +167,15 @@ private String[] buildArgs() { + "jsr305,listenablefuture,talend-component-maven-plugin," + "avro,beam,paranamer,xz,component-api,component-spi,component-runtime-impl," + "component-runtime-manager,component-runtime-design-extension,container-core," - + "component-runtime-beam"); + + "component-runtime-beam," + // smallrye-config has no META-INF/beans.xml and registers its own producer beans + // (e.g. io.smallrye.config.inject.ConfigProducer) programmatically through its + // jakarta.enterprise.inject.spi.Extension; scanning it as a normal (implicit) bean + // archive on top of that causes duplicate bean registrations and + // AmbiguousResolutionException at CDI validation time. component-server's own test + // suite already excludes it the same way via @MeecrowaveConfig(scanningExcludes = + // "smallrye-config"). + + "smallrye-config"); } if (!args.contains("--use-shutdown-hook")) { args.add("--use-shutdown-hook"); diff --git a/component-tools/src/test/java/org/talend/sdk/component/tools/ComponentValidatorTest.java b/component-tools/src/test/java/org/talend/sdk/component/tools/ComponentValidatorTest.java index 6aa430433b7c7..fe2f5d32dcc73 100755 --- a/component-tools/src/test/java/org/talend/sdk/component/tools/ComponentValidatorTest.java +++ b/component-tools/src/test/java/org/talend/sdk/component/tools/ComponentValidatorTest.java @@ -36,7 +36,7 @@ import java.util.Optional; import java.util.stream.Stream; -import javax.inject.Inject; +import jakarta.inject.Inject; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.AfterAllCallback; diff --git a/documentation/module-knowledge.md b/documentation/module-knowledge.md new file mode 100644 index 0000000000000..29316d3340093 --- /dev/null +++ b/documentation/module-knowledge.md @@ -0,0 +1,23 @@ +# Module knowledge — documentation + +[2026-09-23 | QTDI-3358] The connector **sample/example** Java sources under `documentation/` (e.g. +`src/main/java/org/talend/runtime/documentation/component/**`, +`src/main/antora/modules/ROOT/pages/_partials/java/*.java`) must keep `javax.annotation.*` and +`javax.json.*` imports, **not** `jakarta.*` — even though this module also contains the doc-site's +own REST-doc-generator tooling (`SearchIndexation.java`, `Github.java`, `Gravatars.java`, +`Generator.java`, under `org.talend.runtime.documentation` build-tooling packages) which correctly +uses `jakarta.json`/`jakarta.ws.rs` for its own unrelated purposes. The two groups look similar +(same module, same top-level package prefix) but must not be migrated together: the sample files +are compiled and copy-pasted by connector authors into the still-`javax`-based +`component-runtime` — `component-runtime-impl`'s `LifecycleImpl` only discovers +`javax.annotation.PostConstruct`/`PreDestroy` (not the `jakarta` equivalents), and +`RecordConverters`/JSON-B decoding only understands `javax.json.*` types. A `jakarta` import on a +sample silently breaks it at runtime (lifecycle hooks never invoked; JSON values fail to +decode) without any compile-time signal, since the file compiles fine as a standalone +`documentation`-module `.java` source — the breakage only shows up when someone copies the sample +into a real connector plugin executed by `component-runtime`. Round 2 of this ticket's jakarta +migration incorrectly moved 8 such sample files to `jakarta.*`; caught by GitHub's automated PR +review (5 files) plus manual inspection for the same defect (3 more), fixed in Round 5. When +migrating `documentation`'s imports for any future jakarta-related work, classify each file by +*what it is* (connector sample vs. doc-generator tooling) before touching its imports, not by +module or package-prefix alone. diff --git a/documentation/pom.xml b/documentation/pom.xml index 73b04ac898bc1..092cc6a51e4e7 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -55,11 +55,35 @@ false + + + + + org.apache.johnzon + johnzon-core + ${johnzon-jakarta.version} + + + org.apache.johnzon + johnzon-mapper + ${johnzon-jakarta.version} + + + org.apache.johnzon + johnzon-jsonb + ${johnzon-jakarta.version} + + + + - org.apache.geronimo.specs - geronimo-jaxrs_2.1_spec - ${geronimo-jaxrs.version} + jakarta.ws.rs + jakarta.ws.rs-api provided @@ -169,6 +193,7 @@ org.apache.johnzon johnzon-jsonb + ${johnzon-jakarta.version} provided @@ -232,7 +257,7 @@ org.apache.johnzon johnzon-jsonb - ${johnzon.version} + ${johnzon-jakarta.version} org.asciidoctor @@ -285,19 +310,19 @@ ${geronimo-openapi.version} - org.apache.geronimo.specs - geronimo-json_1.1_spec - ${geronimo-json.version} + jakarta.json + jakarta.json-api + ${jakarta.json-api.version} - org.apache.geronimo.specs - geronimo-jsonb_1.0_spec - ${geronimo-jsonb.version} + jakarta.json.bind + jakarta.json.bind-api + ${jakarta.json.bind-api.version} org.apache.johnzon johnzon-jsonb - ${johnzon.version} + ${johnzon-jakarta.version} com.github.crawler-commons @@ -320,9 +345,9 @@ ${commons-text.version} - org.apache.geronimo.specs - geronimo-jaxrs_2.1_spec - ${geronimo-jaxrs.version} + jakarta.ws.rs + jakarta.ws.rs-api + ${jakarta.ws.rs-api.version} org.asciidoctor @@ -415,9 +440,9 @@ ${plexus-sec-dispatcher.version} - org.apache.geronimo.specs - geronimo-jaxrs_2.1_spec - ${geronimo-jaxrs.version} + jakarta.ws.rs + jakarta.ws.rs-api + ${jakarta.ws.rs-api.version} org.talend.sdk.component diff --git a/documentation/src/main/java/org/talend/runtime/documentation/Generator.java b/documentation/src/main/java/org/talend/runtime/documentation/Generator.java index 78e93ab542e17..4d5e1da0606ce 100644 --- a/documentation/src/main/java/org/talend/runtime/documentation/Generator.java +++ b/documentation/src/main/java/org/talend/runtime/documentation/Generator.java @@ -15,6 +15,7 @@ */ package org.talend.runtime.documentation; +import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; import static java.lang.Math.min; import static java.util.Collections.emptyMap; import static java.util.Comparator.comparing; @@ -30,7 +31,6 @@ import static java.util.stream.Collectors.toList; 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 lombok.AccessLevel.PRIVATE; import static org.apache.ziplock.JarLocation.jarLocation; @@ -79,21 +79,21 @@ import java.util.stream.IntStream; import java.util.stream.Stream; -import javax.json.Json; -import javax.json.JsonArray; -import javax.json.JsonBuilderFactory; -import javax.json.JsonNumber; -import javax.json.JsonObject; -import javax.json.JsonString; -import javax.json.JsonValue; -import javax.json.bind.Jsonb; -import javax.json.bind.JsonbBuilder; -import javax.json.bind.JsonbConfig; -import javax.json.bind.config.PropertyOrderStrategy; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.GenericType; +import jakarta.json.Json; +import jakarta.json.JsonArray; +import jakarta.json.JsonBuilderFactory; +import jakarta.json.JsonNumber; +import jakarta.json.JsonObject; +import jakarta.json.JsonString; +import jakarta.json.JsonValue; +import jakarta.json.bind.Jsonb; +import jakarta.json.bind.JsonbBuilder; +import jakarta.json.bind.JsonbConfig; +import jakarta.json.bind.config.PropertyOrderStrategy; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.WebTarget; +import jakarta.ws.rs.core.GenericType; import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.text.WordUtils; diff --git a/documentation/src/main/java/org/talend/runtime/documentation/Github.java b/documentation/src/main/java/org/talend/runtime/documentation/Github.java index 93e976ad70ee5..39ad5bc058c55 100644 --- a/documentation/src/main/java/org/talend/runtime/documentation/Github.java +++ b/documentation/src/main/java/org/talend/runtime/documentation/Github.java @@ -15,13 +15,13 @@ */ package org.talend.runtime.documentation; +import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; import static java.util.Comparator.comparing; import static java.util.Locale.ROOT; import static java.util.Optional.ofNullable; import static java.util.concurrent.CompletableFuture.allOf; 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.nio.charset.StandardCharsets; import java.util.Base64; @@ -36,14 +36,14 @@ import java.util.function.Supplier; import java.util.stream.Stream; -import javax.json.bind.annotation.JsonbProperty; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.GenericType; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.Response; +import jakarta.json.bind.annotation.JsonbProperty; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.WebTarget; +import jakarta.ws.rs.core.GenericType; +import jakarta.ws.rs.core.HttpHeaders; +import jakarta.ws.rs.core.Response; import org.apache.johnzon.jaxrs.jsonb.jaxrs.JsonbJaxrsProvider; import org.talend.sdk.component.maven.MavenDecrypter; diff --git a/documentation/src/main/java/org/talend/runtime/documentation/Gravatars.java b/documentation/src/main/java/org/talend/runtime/documentation/Gravatars.java index 0f5e57def43f8..233e0348e1bff 100644 --- a/documentation/src/main/java/org/talend/runtime/documentation/Gravatars.java +++ b/documentation/src/main/java/org/talend/runtime/documentation/Gravatars.java @@ -15,8 +15,8 @@ */ package org.talend.runtime.documentation; +import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; import static java.util.Optional.ofNullable; -import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; import static lombok.AccessLevel.PRIVATE; import java.io.UnsupportedEncodingException; @@ -24,8 +24,8 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.Response; +import jakarta.ws.rs.client.WebTarget; +import jakarta.ws.rs.core.Response; import lombok.Builder; import lombok.Data; diff --git a/documentation/src/main/java/org/talend/runtime/documentation/SearchIndexation.java b/documentation/src/main/java/org/talend/runtime/documentation/SearchIndexation.java index 54a1009e59979..3e7e358a78a78 100644 --- a/documentation/src/main/java/org/talend/runtime/documentation/SearchIndexation.java +++ b/documentation/src/main/java/org/talend/runtime/documentation/SearchIndexation.java @@ -41,15 +41,15 @@ import java.util.stream.Collector; import java.util.stream.IntStream; -import javax.json.Json; -import javax.json.JsonArrayBuilder; -import javax.json.JsonBuilderFactory; -import javax.json.JsonObject; -import javax.json.JsonObjectBuilder; -import javax.json.bind.Jsonb; -import javax.json.bind.JsonbBuilder; -import javax.json.bind.JsonbConfig; -import javax.json.bind.config.PropertyOrderStrategy; +import jakarta.json.Json; +import jakarta.json.JsonArrayBuilder; +import jakarta.json.JsonBuilderFactory; +import jakarta.json.JsonObject; +import jakarta.json.JsonObjectBuilder; +import jakarta.json.bind.Jsonb; +import jakarta.json.bind.JsonbBuilder; +import jakarta.json.bind.JsonbConfig; +import jakarta.json.bind.config.PropertyOrderStrategy; import crawlercommons.sitemaps.SiteMap; import crawlercommons.sitemaps.SiteMapParser; diff --git a/images/component-server-image/pom.xml b/images/component-server-image/pom.xml index 82007b4e1f4fc..b57597c13b546 100644 --- a/images/component-server-image/pom.xml +++ b/images/component-server-image/pom.xml @@ -36,6 +36,31 @@ ${project.version}-${maven.build.timestamp} + + + + + org.apache.johnzon + johnzon-core + ${johnzon-jakarta.version} + + + org.apache.johnzon + johnzon-mapper + ${johnzon-jakarta.version} + + + org.apache.johnzon + johnzon-jsonb + ${johnzon-jakarta.version} + + + + org.talend.sdk.component diff --git a/images/component-server-image/src/main/java/org/talend/sdk/component/server/image/Startup.java b/images/component-server-image/src/main/java/org/talend/sdk/component/server/image/Startup.java index 9b79426a32b5a..96ea5711450f2 100644 --- a/images/component-server-image/src/main/java/org/talend/sdk/component/server/image/Startup.java +++ b/images/component-server-image/src/main/java/org/talend/sdk/component/server/image/Startup.java @@ -15,9 +15,9 @@ */ package org.talend.sdk.component.server.image; -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.context.Initialized; -import javax.enterprise.event.Observes; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.context.Initialized; +import jakarta.enterprise.event.Observes; import lombok.extern.slf4j.Slf4j; diff --git a/images/component-server-image/src/main/resources/meecrowave.properties b/images/component-server-image/src/main/resources/meecrowave.properties index 831fc6cc864f4..bf098d60c7da7 100644 --- a/images/component-server-image/src/main/resources/meecrowave.properties +++ b/images/component-server-image/src/main/resources/meecrowave.properties @@ -18,11 +18,15 @@ tomcat-skip-jmx = false use-shutdown-hook = false # 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,sigar,\ component-server-model,opentracing-api,codemodel,relaxng,stax,istack,rng,dtd,txw,xsom,common-java5,\ -zstd-jni,beam-vendor,beam-runners +zstd-jni,beam-vendor,beam-runners,smallrye-config # we don't care about that in prod watcher-bouncing = -1 diff --git a/images/component-starter-server-image/pom.xml b/images/component-starter-server-image/pom.xml index 118925d5723d6..1506ec2042f6b 100644 --- a/images/component-starter-server-image/pom.xml +++ b/images/component-starter-server-image/pom.xml @@ -36,6 +36,31 @@ 8080 + + + + + org.apache.johnzon + johnzon-core + ${johnzon-jakarta.version} + + + org.apache.johnzon + johnzon-mapper + ${johnzon-jakarta.version} + + + org.apache.johnzon + johnzon-jsonb + ${johnzon-jakarta.version} + + + + org.talend.sdk.component diff --git a/images/component-starter-server-image/src/main/resources/meecrowave.properties b/images/component-starter-server-image/src/main/resources/meecrowave.properties index 7f98198296189..d061e4589cd82 100644 --- a/images/component-starter-server-image/src/main/resources/meecrowave.properties +++ b/images/component-starter-server-image/src/main/resources/meecrowave.properties @@ -17,9 +17,14 @@ tomcat-access-log-pattern = %h %l %u %t "%r" %s %b "%{Referer}i" "%{User-Agent}i use-shutdown-hook = false # 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 # we don't care about that in prod watcher-bouncing = -1 diff --git a/pom.xml b/pom.xml index 95bf4a0e46364..6c34b2ebba1d1 100644 --- a/pom.xml +++ b/pom.xml @@ -171,10 +171,39 @@ 8.0.14 - 1.2.15 - 2.0.27 - 9.0.121 - 3.6.12 + + 2.1.1 + 4.1.1 + 11.0.26 + 4.1.8 + + + 3.1.0 + 2.1.1 + 4.1.0 + 2.0.1 + 6.0.0 + 2.1.3 + 3.0.2 6.5.0 @@ -197,13 +226,25 @@ 1.1 2.5.2 1.6.0 - 1.3 + + 3.1 + 3.12.4 1.1.1 1.1.1 1.0.2 1.0.12 1.0.3 - 1.2.2 5.14.3 4.8.1 1.3 @@ -297,6 +338,12 @@ false 1.2.21 + + 2.2.0 + + 1.1.4 + 1.0.11 1.7.34 2.25.5 1.9.0 @@ -322,6 +369,27 @@ johnzon-core ${johnzon.version} + + + org.glassfish + javax.json + ${glassfish-javax-json.version} + + + org.eclipse + yasson + ${yasson-javax.version} + org.apache.logging.log4j log4j-api @@ -400,9 +468,9 @@ provided - org.apache.geronimo.config - geronimo-config-impl - ${geronimo-config.version} + io.smallrye.config + smallrye-config + ${smallrye-config.version} org.eclipse.microprofile.config @@ -654,12 +722,53 @@ openwebbeans-spi ${owb.version} + + org.apache.openwebbeans + openwebbeans-impl + ${owb.version} + org.apache.openwebbeans openwebbeans-web ${owb.version} + + jakarta.ws.rs + jakarta.ws.rs-api + ${jakarta.ws.rs-api.version} + + + jakarta.annotation + jakarta.annotation-api + ${jakarta.annotation-api.version} + + + jakarta.enterprise + jakarta.enterprise.cdi-api + ${jakarta.enterprise.cdi-api.version} + + + jakarta.inject + jakarta.inject-api + ${jakarta.inject-api.version} + + + jakarta.servlet + jakarta.servlet-api + ${jakarta.servlet-api.version} + + + jakarta.json + jakarta.json-api + ${jakarta.json-api.version} + + + jakarta.json.bind + jakarta.json.bind-api + ${jakarta.json.bind-api.version} + + com.fasterxml.woodstox woodstox-core @@ -738,10 +847,6 @@ org.jboss.spec.javax.rmi jboss-rmi-api_1.0_spec - - jakarta.activation - jakarta.activation-api - javax.ws.rs javax.ws.rs-api @@ -805,10 +910,6 @@ jakarta.ws.rs jakarta.ws.rs-api - - jakarta.activation - jakarta.activation-api - org.apache.geronimo.specs geronimo-ws-metadata_2.0_spec @@ -856,10 +957,6 @@ jakarta.ws.rs jakarta.ws.rs-api - - jakarta.activation - jakarta.activation-api - @@ -1075,17 +1172,19 @@ org.apache.meecrowave meecrowave-maven-plugin + ${meecrowave.version} org.apache.johnzon johnzon-jaxrs - ${johnzon.version} + ${johnzon-jakarta.version} org.apache.johnzon johnzon-jsonb - ${johnzon.version} + ${johnzon-jakarta.version} org.apache.cxf @@ -1116,10 +1215,6 @@ org.jboss.spec.javax.rmi jboss-rmi-api_1.0_spec - - jakarta.activation - jakarta.activation-api - javax.ws.rs javax.ws.rs-api @@ -1167,10 +1262,6 @@ jakarta.ws.rs jakarta.ws.rs-api - - jakarta.activation - jakarta.activation-api - @@ -1198,10 +1289,6 @@ jakarta.ws.rs jakarta.ws.rs-api - - jakarta.activation - jakarta.activation-api - diff --git a/repository-knowledge.md b/repository-knowledge.md index a52a1c00c8e60..c3ee94e9cead0 100644 --- a/repository-knowledge.md +++ b/repository-knowledge.md @@ -192,6 +192,47 @@ consumers simultaneously; no per-module edit is ever needed for a CXF version bu --- +## Build / validation gotchas + +### RAT check can fail locally on untracked ai-commons tooling files (CI is unaffected) + +[2026-09-22 | QTDI-3358] The root pom's `apache-rat-plugin` excludes (`**/.*`, `**/.*/*`) only +match files directly inside a dot-folder, not files nested further down — e.g. +`.ai-commons/agents/ai-cve/scripts/sample.env` (3 levels deep) is **not** excluded and fails +`mvn clean install -Dgpg.skip=true -Denforcer.skip=true` (the documented CI-mirroring command) +with "Too many files with unapproved license" when di-ai-commons tooling is installed locally. +Since `.ai-commons/` is itself gitignored and untracked, CI never sees this — it is a local-only +false failure. **Fix**: add `-Drat.skip=true` when running a full local reactor validation build +in a checkout that has `.ai-commons/` present, or `rm -rf` any stray manually-created scratch +directories/files before running RAT-sensitive goals. + +### Full-reactor `documentation` build regenerates two `.adoc` files as a side effect + +[2026-09-22 | QTDI-3358] Building the `documentation` module (or the full reactor, which builds it +last) regenerates `generated_rest-resources.adoc` (from CXF/JAX-RS-annotated classes) and +`generated_contributors.adoc` (from git history) every time — even when only running a build for +unrelated verification purposes. If any of the currently-active CXF consumers uses an OpenAPI/doc +plugin without a matching release for the annotation namespace in use (e.g. +`geronimo-openapi-maven-plugin` has no `jakarta.*`-namespace release as of this writing), the +regenerated `generated_rest-resources.adoc` content can differ from — or actively regress — +the committed version. Always run `git status`/`git diff` on both files after any local +verification build and `git checkout HEAD -- ` to revert unintended regeneration before +committing or rebasing. + +### `-T 1C` parallel reactor builds can hang a `component-runtime-manager` HTTP-client test + +[2026-09-22 | QTDI-3358] `component-runtime-manager`'s `HttpClientFactoryImpl`-backed test(s) make +a real (non-mocked) network call with no read timeout. Run standalone (`mvn test -pl +component-runtime-manager`) the full suite (316 tests) completes cleanly in ~10s. Run as part of a +`-T 1C` parallel full-reactor build alongside other modules, the same test can stall indefinitely +(confirmed via `jstack` — blocked in `SocketDispatcher.read`) — likely resource contention under +concurrent module execution. **Workaround**: validate large changesets with sequential, per-module +`mvn test -pl ` runs (per `AGENTS.md`'s documented single-module invocation) rather than a +parallel (`-T 1C`) full-reactor test run; reserve `-T 1C` for compile/package-only validation +(`-DskipTests`), where it is reliable. + +--- + ## Coding rules delta No known repo-specific exceptions to the shared [coding-rules.md](https://github.com/Talend/di-ai-commons/blob/main/knowledge/rules/coding-rules.md). diff --git a/talend-component-maven-plugin/pom.xml b/talend-component-maven-plugin/pom.xml index 4af3c2d481c18..5ee386e72e399 100644 --- a/talend-component-maven-plugin/pom.xml +++ b/talend-component-maven-plugin/pom.xml @@ -41,6 +41,28 @@ salesforce + + + + + org.apache.johnzon + johnzon-core + ${johnzon-jakarta.version} + + + org.apache.johnzon + johnzon-mapper + ${johnzon-jakarta.version} + + + + org.talend.sdk.component @@ -90,18 +112,22 @@ ${maven-shared-utils.version} - org.apache.geronimo.specs - geronimo-jsonb_1.0_spec - ${geronimo-jsonb.version} + + jakarta.json.bind + jakarta.json.bind-api - org.apache.geronimo.specs - geronimo-json_1.1_spec - ${geronimo-json.version} + jakarta.json + jakarta.json-api org.apache.johnzon johnzon-jsonb + ${johnzon-jakarta.version} diff --git a/talend-component-maven-plugin/src/main/java/org/talend/sdk/component/maven/ComponentMetadataMojo.java b/talend-component-maven-plugin/src/main/java/org/talend/sdk/component/maven/ComponentMetadataMojo.java index 4c648e9fa4f87..a5e7cbbf57d54 100644 --- a/talend-component-maven-plugin/src/main/java/org/talend/sdk/component/maven/ComponentMetadataMojo.java +++ b/talend-component-maven-plugin/src/main/java/org/talend/sdk/component/maven/ComponentMetadataMojo.java @@ -27,9 +27,9 @@ import java.util.Locale; 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.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; diff --git a/vault-client/pom.xml b/vault-client/pom.xml index 1528875b1ceb4..6ef1b50c1c255 100644 --- a/vault-client/pom.xml +++ b/vault-client/pom.xml @@ -31,10 +31,36 @@ ${talend.build.name.base}.vault.client + + + + + org.apache.johnzon + johnzon-core + ${johnzon-jakarta.version} + + + org.apache.johnzon + johnzon-mapper + ${johnzon-jakarta.version} + + + org.apache.johnzon + johnzon-jsonb + ${johnzon-jakarta.version} + + + + org.apache.meecrowave meecrowave-core + ${meecrowave.version} org.apache.xbean @@ -70,8 +96,8 @@ microprofile-config-api - org.apache.geronimo.config - geronimo-config-impl + io.smallrye.config + smallrye-config org.apache.geronimo.specs diff --git a/vault-client/src/main/java/org/talend/sdk/components/vault/client/ClockSetup.java b/vault-client/src/main/java/org/talend/sdk/components/vault/client/ClockSetup.java index 192b1b2ee9500..68b33032fe7ae 100644 --- a/vault-client/src/main/java/org/talend/sdk/components/vault/client/ClockSetup.java +++ b/vault-client/src/main/java/org/talend/sdk/components/vault/client/ClockSetup.java @@ -17,8 +17,8 @@ import java.time.Clock; -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.inject.Produces; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.inject.Produces; @ApplicationScoped public class ClockSetup { diff --git a/vault-client/src/main/java/org/talend/sdk/components/vault/client/VaultClient.java b/vault-client/src/main/java/org/talend/sdk/components/vault/client/VaultClient.java index 74cf8485a02c8..f85f9de381e9c 100644 --- a/vault-client/src/main/java/org/talend/sdk/components/vault/client/VaultClient.java +++ b/vault-client/src/main/java/org/talend/sdk/components/vault/client/VaultClient.java @@ -15,6 +15,8 @@ */ package org.talend.sdk.components.vault.client; +import static jakarta.ws.rs.client.Entity.entity; +import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; import static java.util.Optional.of; import static java.util.Optional.ofNullable; import static java.util.concurrent.CompletableFuture.completedFuture; @@ -23,8 +25,6 @@ import static java.util.function.Function.identity; import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toMap; -import static javax.ws.rs.client.Entity.entity; -import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; import java.nio.charset.StandardCharsets; import java.time.Clock; @@ -51,19 +51,20 @@ import java.util.function.Supplier; import java.util.regex.Pattern; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; import javax.cache.Cache; -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.context.Initialized; -import javax.enterprise.event.Observes; -import javax.inject.Inject; -import javax.json.bind.annotation.JsonbProperty; -import javax.servlet.ServletContext; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; + +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.context.Initialized; +import jakarta.enterprise.event.Observes; +import jakarta.inject.Inject; +import jakarta.json.bind.annotation.JsonbProperty; +import jakarta.servlet.ServletContext; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.client.WebTarget; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; import org.eclipse.microprofile.config.inject.ConfigProperty; import org.talend.sdk.components.vault.configuration.Documentation; diff --git a/vault-client/src/main/java/org/talend/sdk/components/vault/client/VaultClientSetup.java b/vault-client/src/main/java/org/talend/sdk/components/vault/client/VaultClientSetup.java index ef9b9d9c1966a..a17566d2877b9 100644 --- a/vault-client/src/main/java/org/talend/sdk/components/vault/client/VaultClientSetup.java +++ b/vault-client/src/main/java/org/talend/sdk/components/vault/client/VaultClientSetup.java @@ -37,17 +37,18 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Stream; -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.inject.Disposes; -import javax.enterprise.inject.Produces; -import javax.inject.Inject; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.WebTarget; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.inject.Disposes; +import jakarta.enterprise.inject.Produces; +import jakarta.inject.Inject; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.ClientBuilder; +import jakarta.ws.rs.client.WebTarget; import org.apache.cxf.transport.https.httpclient.DefaultHostnameVerifier; import org.eclipse.microprofile.config.inject.ConfigProperty; diff --git a/vault-client/src/main/java/org/talend/sdk/components/vault/client/VaultHttp.java b/vault-client/src/main/java/org/talend/sdk/components/vault/client/VaultHttp.java index f5e1dd44ee5d9..20c6ece3ae044 100644 --- a/vault-client/src/main/java/org/talend/sdk/components/vault/client/VaultHttp.java +++ b/vault-client/src/main/java/org/talend/sdk/components/vault/client/VaultHttp.java @@ -23,7 +23,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.Target; -import javax.inject.Qualifier; +import jakarta.inject.Qualifier; @Qualifier @Target({ METHOD, FIELD, PARAMETER }) diff --git a/vault-client/src/main/java/org/talend/sdk/components/vault/jcache/CacheConfigurationFactory.java b/vault-client/src/main/java/org/talend/sdk/components/vault/jcache/CacheConfigurationFactory.java index eaeac05f61e7a..b200830bed775 100644 --- a/vault-client/src/main/java/org/talend/sdk/components/vault/jcache/CacheConfigurationFactory.java +++ b/vault-client/src/main/java/org/talend/sdk/components/vault/jcache/CacheConfigurationFactory.java @@ -23,8 +23,9 @@ import javax.cache.configuration.MutableConfiguration; import javax.cache.expiry.CreatedExpiryPolicy; import javax.cache.expiry.Duration; -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; import org.talend.sdk.components.vault.configuration.Documentation; diff --git a/vault-client/src/main/java/org/talend/sdk/components/vault/jcache/JCacheSetup.java b/vault-client/src/main/java/org/talend/sdk/components/vault/jcache/JCacheSetup.java index af566ddc79e36..6c1999f171bae 100644 --- a/vault-client/src/main/java/org/talend/sdk/components/vault/jcache/JCacheSetup.java +++ b/vault-client/src/main/java/org/talend/sdk/components/vault/jcache/JCacheSetup.java @@ -25,10 +25,11 @@ import javax.cache.CacheManager; import javax.cache.Caching; import javax.cache.spi.CachingProvider; -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.inject.Disposes; -import javax.enterprise.inject.Produces; -import javax.inject.Inject; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.inject.Disposes; +import jakarta.enterprise.inject.Produces; +import jakarta.inject.Inject; import org.eclipse.microprofile.config.inject.ConfigProperty; import org.talend.sdk.components.vault.client.DecryptedValue; @@ -45,8 +46,12 @@ public class JCacheSetup { @Inject @Documentation("JCache `CacheManager` properties used to initialized the instance.") - @ConfigProperty(name = "talend.vault.cache.jcache.manager.properties", defaultValue = "") - private String configurationProperties; + // SmallRye Config's built-in String converter unconditionally treats a resolved empty-string value as + // null (SRCFG00040), so a plain String field with defaultValue = "" fails eager @ConfigProperty + // validation under SmallRye - Optional (no defaultValue) is the MicroProfile Config idiom for + // "no value configured" and avoids the empty-string conversion path entirely. See QTDI-3358 notes. + @ConfigProperty(name = "talend.vault.cache.jcache.manager.properties") + private Optional configurationProperties; @Inject private CacheConfigurationFactory cacheConfiguration; @@ -66,7 +71,7 @@ public void releaseCachingProvider(@Disposes final CachingProvider provider) { public CacheManager cacheManager(final CachingProvider provider) { return provider .getCacheManager(URI.create(configurationUri), Thread.currentThread().getContextClassLoader(), - Optional.of(configurationProperties).filter(it -> !it.isEmpty()).map(it -> { + configurationProperties.filter(it -> !it.isEmpty()).map(it -> { final Properties properties = new Properties(); try (final StringReader reader = new StringReader(it)) { properties.load(reader); diff --git a/vault-client/src/main/resources/META-INF/beans.xml b/vault-client/src/main/resources/META-INF/beans.xml index 908aa55e6a126..35900e5da8c0c 100644 --- a/vault-client/src/main/resources/META-INF/beans.xml +++ b/vault-client/src/main/resources/META-INF/beans.xml @@ -14,8 +14,8 @@ limitations under the License. --> + https://jakarta.ee/xml/ns/jakartaee + https://jakarta.ee/xml/ns/jakartaee/beans_4_0.xsd"/> diff --git a/vault-client/src/test/java/org/talend/sdk/components/vault/client/VaultClientTest.java b/vault-client/src/test/java/org/talend/sdk/components/vault/client/VaultClientTest.java index ff2c0b19db416..34d09c7ca7a91 100644 --- a/vault-client/src/test/java/org/talend/sdk/components/vault/client/VaultClientTest.java +++ b/vault-client/src/test/java/org/talend/sdk/components/vault/client/VaultClientTest.java @@ -15,7 +15,7 @@ */ package org.talend.sdk.components.vault.client; -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; import static org.junit.jupiter.api.Assertions.fail; @@ -28,23 +28,33 @@ import java.util.concurrent.CompletionException; import java.util.function.Predicate; -import javax.enterprise.inject.se.SeContainer; -import javax.enterprise.inject.se.SeContainerInitializer; -import javax.inject.Inject; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.Response; +import jakarta.enterprise.inject.se.SeContainer; +import jakarta.enterprise.inject.se.SeContainerInitializer; +import jakarta.inject.Inject; +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.client.Client; +import jakarta.ws.rs.client.Entity; +import jakarta.ws.rs.client.WebTarget; +import jakarta.ws.rs.core.Response; import org.apache.meecrowave.Meecrowave; -import org.apache.meecrowave.junit5.MonoMeecrowaveConfig; +import org.apache.meecrowave.junit5.MeecrowaveConfig; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; import org.talend.sdk.components.vault.server.error.ErrorPayload; -@MonoMeecrowaveConfig +// scanningExcludes stops OpenWebBeans' classpath-wide bean scan from ALSO picking up SmallRye Config's +// ConfigProducer (it registers itself via its own CDI extension already), which otherwise causes a +// duplicate-bean AmbiguousResolutionException for every @ConfigProperty injection point - see QTDI-3358. +// @MonoMeecrowaveConfig has no per-test-class configuration point for this, hence the switch to +// @MeecrowaveConfig (this is the only test class in this module, so the shared-container optimization +// Mono offers is not needed here). @TestInstance(PER_CLASS) makes MeecrowaveExtension boot the container +// once per class (beforeAll/afterAll) instead of once per method (beforeEach/afterEach) - the latter +// triggers repeated OWB deployments that collide on internal bean ids (DuplicateDefinitionException). +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@MeecrowaveConfig(scanningExcludes = "smallrye-config") class VaultClientTest { @Inject diff --git a/vault-client/src/test/java/org/talend/sdk/components/vault/client/vault/VaultMock.java b/vault-client/src/test/java/org/talend/sdk/components/vault/client/vault/VaultMock.java index f513fdaccecf4..52b6d622b2429 100644 --- a/vault-client/src/test/java/org/talend/sdk/components/vault/client/vault/VaultMock.java +++ b/vault-client/src/test/java/org/talend/sdk/components/vault/client/vault/VaultMock.java @@ -15,30 +15,30 @@ */ package org.talend.sdk.components.vault.client.vault; +import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; +import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; import static java.util.Collections.singletonList; -import static javax.ws.rs.core.MediaType.APPLICATION_JSON; -import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.HashMap; import java.util.Map; -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; -import javax.ws.rs.Consumes; -import javax.ws.rs.DefaultValue; -import javax.ws.rs.HeaderParam; -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.WebApplicationException; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.DefaultValue; +import jakarta.ws.rs.HeaderParam; +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.WebApplicationException; +import jakarta.ws.rs.core.Context; +import jakarta.ws.rs.core.HttpHeaders; +import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.Response.Status; import org.talend.sdk.components.vault.client.VaultClient;