This is an automated email from the ASF dual-hosted git repository. tballison pushed a commit to branch TIKA-4840-strict-config in repository https://gitbox.apache.org/repos/asf/tika.git
commit 1031100da12066bfaf9603df3d7f95b2f7792d3c Author: tallison <[email protected]> AuthorDate: Mon Aug 24 15:52:59 2026 -0400 TIKA-4840: host-provided Jackson for pipes plugins; one strict PluginJson mapper for plugin configs --- CHANGES.txt | 10 +++ .../ROOT/pages/pipes/plugins/writing-a-plugin.adoc | 24 ++++++- tika-pipes/tika-pipes-plugins/pom.xml | 23 ++++++- .../tika-pipes-atlassian-jwt/pom.xml | 8 --- .../config/AtlassianJwtFetcherConfig.java | 3 +- .../tika-pipes-plugins/tika-pipes-az-blob/pom.xml | 4 -- .../pipes/emitter/azblob/AZBlobEmitterConfig.java | 3 +- .../fetcher/azblob/config/AZBlobFetcherConfig.java | 3 +- .../iterator/azblob/AZBlobPipesIteratorConfig.java | 3 +- .../pipes/iterator/csv/CSVPipesIteratorConfig.java | 3 +- .../tika/pipes/emitter/es/ESEmitterConfig.java | 3 +- .../tika/pipes/reporter/es/ESReporterConfig.java | 3 +- .../tika-pipes-file-system/pom.xml | 5 -- .../pipes/emitter/fs/FileSystemEmitterConfig.java | 3 +- .../emitter/fs/FileSystemEmitterRuntimeConfig.java | 3 +- .../pipes/fetcher/fs/FileSystemFetcherConfig.java | 3 +- .../iterator/fs/FileSystemPipesIteratorConfig.java | 3 +- .../reporter/fs/FileSystemReporterConfig.java | 3 +- .../tika/pipes/emitter/gcs/GCSEmitterConfig.java | 3 +- .../pipes/fetcher/gcs/config/GCSFetcherConfig.java | 3 +- .../pipes/iterator/gcs/GCSPipesIteratorConfig.java | 3 +- .../tika-pipes-google-drive/pom.xml | 8 --- .../config/GoogleDriveFetcherConfig.java | 3 +- .../tika-pipes-plugins/tika-pipes-http/pom.xml | 8 --- .../fetcher/http/config/HttpFetcherConfig.java | 3 +- .../tika/pipes/emitter/jdbc/JDBCEmitterConfig.java | 3 +- .../iterator/jdbc/JDBCPipesIteratorConfig.java | 3 +- .../reporter/jdbc/JDBCPipesReporterConfig.java | 3 +- .../json/JsonPipesIteratorConfig.java | 3 +- .../tika-pipes-plugins/tika-pipes-kafka/pom.xml | 5 -- .../pipes/emitter/kafka/KafkaEmitterConfig.java | 3 +- .../iterator/kafka/KafkaPipesIteratorConfig.java | 3 +- .../config/MicrosoftGraphFetcherConfig.java | 3 +- .../pipes/emitter/opensearch/HttpClientConfig.java | 4 +- .../opensearch/OpenSearchEmitterConfig.java | 3 +- .../reporter/opensearch/HttpClientConfig.java | 4 +- .../opensearch/OpenSearchReporterConfig.java | 3 +- .../tika-pipes-plugins/tika-pipes-s3/pom.xml | 5 -- .../tika/pipes/emitter/s3/S3EmitterConfig.java | 3 +- .../pipes/fetcher/s3/config/S3FetcherConfig.java | 3 +- .../pipes/iterator/s3/S3PipesIteratorConfig.java | 3 +- .../tika-pipes-plugins/tika-pipes-solr/pom.xml | 4 -- .../tika/pipes/emitter/solr/SolrEmitterConfig.java | 3 +- .../iterator/solr/SolrPipesIteratorConfig.java | 3 +- .../java/org/apache/tika/plugins/PluginJson.java | 65 ++++++++++++++++++ .../org/apache/tika/plugins/PluginJsonTest.java | 80 ++++++++++++++++++++++ 46 files changed, 267 insertions(+), 83 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index eea5ad329b..2d83ea0a8e 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,15 @@ Release 4.1.0 - unreleased + * Pipes plugins no longer bundle their own Jackson: jackson-core, -databind + and -annotations are provided by the host (tika-serialization) and the + plugins parent pom now bans bundling them, so a mapper can cross the + plugin boundary without a second copy of the Jackson classes (seven plugin + zips shipped one). Plugin configuration JSON is parsed by one shared + mapper, PluginJson (tika-plugins-core), which rejects unknown keys, + numbers for enums and duplicate keys, and accepts + // and /* */ comments; the 33 per-plugin *Config classes use it instead of + their own bare ObjectMapper (TIKA-4840). + * The Kafka pipes iterator no longer stops at the first empty poll. A newly subscribed consumer spends its first poll(s) joining the group and returns empty even when the topic has a backlog, so the iterator could enqueue zero diff --git a/docs/modules/ROOT/pages/pipes/plugins/writing-a-plugin.adoc b/docs/modules/ROOT/pages/pipes/plugins/writing-a-plugin.adoc index 3bc6f3299a..03f28cf4f4 100644 --- a/docs/modules/ROOT/pages/pipes/plugins/writing-a-plugin.adoc +++ b/docs/modules/ROOT/pages/pipes/plugins/writing-a-plugin.adoc @@ -124,8 +124,12 @@ public class MyFetcher extends AbstractTikaExtension implements Fetcher { } } ---- -<1> Config arrives as a **JSON string**, and the plugin parses it with its own Jackson. Nothing -richer crosses the boundary — see <<classloading>>. +<1> Config arrives as a **JSON string**; nothing richer crosses the boundary — see +<<classloading>>. The in-tree plugins parse it with `org.apache.tika.plugins.PluginJson` +(`PluginJson.read(json, MyFetcherConfig.class)`), the host's strict mapper: comments allowed, +unknown keys, duplicate keys and numbers-for-enums rejected. Using it is optional — the +boundary is the `Fetcher`, not how it is configured — but see the Jackson rule under +<<classloading>> before deciding. IMPORTANT: `Fetcher` implementations must be thread-safe. One instance serves every concurrent request against that fetcher id. @@ -275,6 +279,20 @@ of a plugin that loads cleanly and then behaves as if it were not there — or o The same reasoning covers logging: leave `org.slf4j` and `org.apache.logging.log4j` to the host so plugin logs land in the host's configuration. +Jackson is the one library with a choice, and it is either/or: + +* **Host Jackson (the default, what the in-tree plugins do):** `jackson-core`, `jackson-databind` + and `jackson-annotations` `provided`, absent from `lib/`. Every Tika host carries them (via + `tika-serialization`), and you may then use `PluginJson` and other host Jackson types. +* **Your own Jackson:** only if a library you depend on needs a version the host does not ship. + Bundle it (`compile` scope), and then never touch a host Jackson object — not `PluginJson`, not + `JsonMetadataList`, nothing returning an `ObjectMapper` or `JsonNode`. Your `ObjectMapper` and + the host's are different `Class` objects, and the first assignment between them fails with a + `LinkageError` or `ClassCastException`. Parse `ExtensionConfig.json()` with your own mapper. + +Never both. The in-tree plugins' parent pom enforces the first choice; a third-party plugin +choosing the second must not inherit that rule. + Everything else — your own transitive libraries — belongs in `lib/`. == Installing and configuring @@ -367,6 +385,8 @@ java -Dtika.plugin.dev.mode=true ... * `tika-core`, `tika-pipes-api`, `tika-plugins-core`, `tika-serialization`, `tika-pipes-core`, `tika-pipes-iterator-commons`, `pf4j` and the logging implementations `provided`, and absent from `lib/`. +* Jackson either `provided` (and then `PluginJson` is yours to use) or bundled (and then no host + Jackson type is) — never a mix. * The zip — not an unpacked directory — dropped in a `plugin-roots` directory. * `getName()` unique against every other loaded plugin. diff --git a/tika-pipes/tika-pipes-plugins/pom.xml b/tika-pipes/tika-pipes-plugins/pom.xml index cb51738f24..187bf0e92d 100644 --- a/tika-pipes/tika-pipes-plugins/pom.xml +++ b/tika-pipes/tika-pipes-plugins/pom.xml @@ -88,6 +88,23 @@ <version>${project.version}</version> <scope>provided</scope> </dependency> + <!-- host-supplied via tika-serialization: a plugin that bundles its own Jackson gets a + second ObjectMapper class, and any mapper crossing the plugin boundary fails to link --> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-annotations</artifactId> + <scope>provided</scope> + </dependency> <!-- logging is host-supplied --> <dependency> <groupId>org.slf4j</groupId> @@ -169,6 +186,7 @@ <excludes> <exclude>org.slf4j</exclude> <exclude>org.apache.logging.log4j</exclude> + <exclude>com.fasterxml.jackson.core</exclude> </excludes> <!-- the artifacts this module declares provided; anything else in these groups needs a provided declaration here before it may be depended on --> @@ -178,8 +196,11 @@ <include>org.apache.logging.log4j:log4j-api</include> <include>org.apache.logging.log4j:log4j-core</include> <include>org.apache.logging.log4j:log4j-slf4j2-impl</include> + <include>com.fasterxml.jackson.core:jackson-core</include> + <include>com.fasterxml.jackson.core:jackson-databind</include> + <include>com.fasterxml.jackson.core:jackson-annotations</include> </includes> - <message>logging is host-supplied: add a provided-scope declaration in tika-pipes-plugins/pom.xml (and to this rule's include list) rather than bundling this artifact in the plugin zip</message> + <message>logging and Jackson are host-supplied: add a provided-scope declaration in tika-pipes-plugins/pom.xml (and to this rule's include list) rather than bundling this artifact in the plugin zip. A plugin whose SDK genuinely needs its own Jackson may bundle it (compile scope, skip this execution in its pom) but must then use no host Jackson type -- not PluginJson -- since the two ObjectMapper classes cannot be assigned to each other.</message> </bannedDependencies> </rules> <fail>true</fail> diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-atlassian-jwt/pom.xml b/tika-pipes/tika-pipes-plugins/tika-pipes-atlassian-jwt/pom.xml index d7544904cd..3e915d7b93 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-atlassian-jwt/pom.xml +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-atlassian-jwt/pom.xml @@ -53,14 +53,6 @@ <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </dependency> - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-databind</artifactId> - </dependency> - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-annotations</artifactId> - </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-atlassian-jwt/src/main/java/org/apache/tika/pipes/fetcher/atlassianjwt/config/AtlassianJwtFetcherConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-atlassian-jwt/src/main/java/org/apache/tika/pipes/fetcher/atlassianjwt/config/AtlassianJwtFetcherConfig.java index 452d6fc53c..e3f8f1e2a7 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-atlassian-jwt/src/main/java/org/apache/tika/pipes/fetcher/atlassianjwt/config/AtlassianJwtFetcherConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-atlassian-jwt/src/main/java/org/apache/tika/pipes/fetcher/atlassianjwt/config/AtlassianJwtFetcherConfig.java @@ -25,10 +25,11 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; +import org.apache.tika.plugins.PluginJson; public class AtlassianJwtFetcherConfig { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static AtlassianJwtFetcherConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/pom.xml b/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/pom.xml index 0e9c49d145..ef9e38677b 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/pom.xml +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/pom.xml @@ -46,10 +46,6 @@ <groupId>com.azure</groupId> <artifactId>azure-storage-blob</artifactId> </dependency> - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-databind</artifactId> - </dependency> </dependencies> <build> diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/emitter/azblob/AZBlobEmitterConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/emitter/azblob/AZBlobEmitterConfig.java index e200a8cc44..72b175c46c 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/emitter/azblob/AZBlobEmitterConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/emitter/azblob/AZBlobEmitterConfig.java @@ -21,6 +21,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; +import org.apache.tika.plugins.PluginJson; public record AZBlobEmitterConfig( String sasToken, @@ -31,7 +32,7 @@ public record AZBlobEmitterConfig( @JsonProperty(defaultValue = "false") boolean overwriteExisting ) { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static AZBlobEmitterConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/fetcher/azblob/config/AZBlobFetcherConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/fetcher/azblob/config/AZBlobFetcherConfig.java index d62a512a05..1d5dfeb4ff 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/fetcher/azblob/config/AZBlobFetcherConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/fetcher/azblob/config/AZBlobFetcherConfig.java @@ -20,10 +20,11 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; +import org.apache.tika.plugins.PluginJson; public class AZBlobFetcherConfig { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static AZBlobFetcherConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/iterator/azblob/AZBlobPipesIteratorConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/iterator/azblob/AZBlobPipesIteratorConfig.java index ef3d78a49a..2cea20ea08 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/iterator/azblob/AZBlobPipesIteratorConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/iterator/azblob/AZBlobPipesIteratorConfig.java @@ -23,10 +23,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; import org.apache.tika.pipes.pipesiterator.PipesIteratorConfig; +import org.apache.tika.plugins.PluginJson; public class AZBlobPipesIteratorConfig extends PipesIteratorConfig { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static AZBlobPipesIteratorConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-csv/src/main/java/org/apache/tika/pipes/iterator/csv/CSVPipesIteratorConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-csv/src/main/java/org/apache/tika/pipes/iterator/csv/CSVPipesIteratorConfig.java index 3a5231821d..28cfd0e8da 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-csv/src/main/java/org/apache/tika/pipes/iterator/csv/CSVPipesIteratorConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-csv/src/main/java/org/apache/tika/pipes/iterator/csv/CSVPipesIteratorConfig.java @@ -24,10 +24,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; import org.apache.tika.pipes.pipesiterator.PipesIteratorConfig; +import org.apache.tika.plugins.PluginJson; public class CSVPipesIteratorConfig extends PipesIteratorConfig { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static CSVPipesIteratorConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-es/src/main/java/org/apache/tika/pipes/emitter/es/ESEmitterConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-es/src/main/java/org/apache/tika/pipes/emitter/es/ESEmitterConfig.java index 288098957b..5f1909891d 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-es/src/main/java/org/apache/tika/pipes/emitter/es/ESEmitterConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-es/src/main/java/org/apache/tika/pipes/emitter/es/ESEmitterConfig.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; +import org.apache.tika.plugins.PluginJson; /** * Configuration for the ES emitter. @@ -49,7 +50,7 @@ public record ESEmitterConfig(String esUrl, String idField, OVERWRITE, UPSERT } - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static ESEmitterConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-es/src/main/java/org/apache/tika/pipes/reporter/es/ESReporterConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-es/src/main/java/org/apache/tika/pipes/reporter/es/ESReporterConfig.java index 023f868df1..88bba68c8a 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-es/src/main/java/org/apache/tika/pipes/reporter/es/ESReporterConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-es/src/main/java/org/apache/tika/pipes/reporter/es/ESReporterConfig.java @@ -24,13 +24,14 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; import org.apache.tika.metadata.ReservedNamespaces; import org.apache.tika.pipes.emitter.es.HttpClientConfig; +import org.apache.tika.plugins.PluginJson; import org.apache.tika.utils.StringUtils; public record ESReporterConfig(String esUrl, Set<String> includes, Set<String> excludes, String keyPrefix, boolean includeRouting, String apiKey, HttpClientConfig httpClientConfig) { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static ESReporterConfig load(final String json) throws TikaConfigException { ESReporterConfig config; diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/pom.xml b/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/pom.xml index 143268ed96..1c9436af94 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/pom.xml +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/pom.xml @@ -41,11 +41,6 @@ <version>${project.version}</version> <scope>provided</scope> </dependency> - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-databind</artifactId> - <scope>provided</scope> - </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/emitter/fs/FileSystemEmitterConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/emitter/fs/FileSystemEmitterConfig.java index 54c6530685..10d3cba1ac 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/emitter/fs/FileSystemEmitterConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/emitter/fs/FileSystemEmitterConfig.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; +import org.apache.tika.plugins.PluginJson; public record FileSystemEmitterConfig(String basePath, String fileExtension, ON_EXISTS onExists, boolean prettyPrint, boolean allowAbsolutePaths) { @@ -34,7 +35,7 @@ public record FileSystemEmitterConfig(String basePath, String fileExtension, ON_ } } - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static FileSystemEmitterConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/emitter/fs/FileSystemEmitterRuntimeConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/emitter/fs/FileSystemEmitterRuntimeConfig.java index 111f236882..517a582153 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/emitter/fs/FileSystemEmitterRuntimeConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/emitter/fs/FileSystemEmitterRuntimeConfig.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; +import org.apache.tika.plugins.PluginJson; /** * Runtime configuration for FileSystemEmitter. @@ -28,7 +29,7 @@ import org.apache.tika.exception.TikaConfigException; */ public class FileSystemEmitterRuntimeConfig { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static FileSystemEmitterRuntimeConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/fetcher/fs/FileSystemFetcherConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/fetcher/fs/FileSystemFetcherConfig.java index 7ee64e38d9..cad2314210 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/fetcher/fs/FileSystemFetcherConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/fetcher/fs/FileSystemFetcherConfig.java @@ -20,10 +20,11 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; +import org.apache.tika.plugins.PluginJson; public class FileSystemFetcherConfig { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static FileSystemFetcherConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/iterator/fs/FileSystemPipesIteratorConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/iterator/fs/FileSystemPipesIteratorConfig.java index 61eeeb66a6..41011f9a46 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/iterator/fs/FileSystemPipesIteratorConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/iterator/fs/FileSystemPipesIteratorConfig.java @@ -24,10 +24,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; import org.apache.tika.pipes.pipesiterator.PipesIteratorConfig; +import org.apache.tika.plugins.PluginJson; public class FileSystemPipesIteratorConfig extends PipesIteratorConfig { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static FileSystemPipesIteratorConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/reporter/fs/FileSystemReporterConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/reporter/fs/FileSystemReporterConfig.java index 816c8c9c8f..036e288484 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/reporter/fs/FileSystemReporterConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/reporter/fs/FileSystemReporterConfig.java @@ -23,10 +23,11 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; +import org.apache.tika.plugins.PluginJson; public record FileSystemReporterConfig(Path statusFile, long reportUpdateMs) implements Serializable { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static FileSystemReporterConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/emitter/gcs/GCSEmitterConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/emitter/gcs/GCSEmitterConfig.java index 80f2241118..8d1c893a5a 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/emitter/gcs/GCSEmitterConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/emitter/gcs/GCSEmitterConfig.java @@ -21,6 +21,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; +import org.apache.tika.plugins.PluginJson; public record GCSEmitterConfig( String projectId, @@ -29,7 +30,7 @@ public record GCSEmitterConfig( @JsonProperty(defaultValue = "json") String fileExtension ) { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static GCSEmitterConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/fetcher/gcs/config/GCSFetcherConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/fetcher/gcs/config/GCSFetcherConfig.java index 4c25d37987..74d2277f69 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/fetcher/gcs/config/GCSFetcherConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/fetcher/gcs/config/GCSFetcherConfig.java @@ -20,10 +20,11 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; +import org.apache.tika.plugins.PluginJson; public class GCSFetcherConfig { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static GCSFetcherConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/iterator/gcs/GCSPipesIteratorConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/iterator/gcs/GCSPipesIteratorConfig.java index d87fea102a..1a48e5d81e 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/iterator/gcs/GCSPipesIteratorConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/iterator/gcs/GCSPipesIteratorConfig.java @@ -23,10 +23,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; import org.apache.tika.pipes.pipesiterator.PipesIteratorConfig; +import org.apache.tika.plugins.PluginJson; public class GCSPipesIteratorConfig extends PipesIteratorConfig { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static GCSPipesIteratorConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-google-drive/pom.xml b/tika-pipes/tika-pipes-plugins/tika-pipes-google-drive/pom.xml index ac0a5f1517..deae544620 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-google-drive/pom.xml +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-google-drive/pom.xml @@ -103,14 +103,6 @@ <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </dependency> - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-databind</artifactId> - </dependency> - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-annotations</artifactId> - </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-google-drive/src/main/java/org/apache/tika/pipes/fetcher/googledrive/config/GoogleDriveFetcherConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-google-drive/src/main/java/org/apache/tika/pipes/fetcher/googledrive/config/GoogleDriveFetcherConfig.java index 1375dda11c..31fe6cc180 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-google-drive/src/main/java/org/apache/tika/pipes/fetcher/googledrive/config/GoogleDriveFetcherConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-google-drive/src/main/java/org/apache/tika/pipes/fetcher/googledrive/config/GoogleDriveFetcherConfig.java @@ -23,10 +23,11 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; +import org.apache.tika.plugins.PluginJson; public class GoogleDriveFetcherConfig { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static GoogleDriveFetcherConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-http/pom.xml b/tika-pipes/tika-pipes-plugins/tika-pipes-http/pom.xml index 7f69f48875..d322977e0c 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-http/pom.xml +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-http/pom.xml @@ -53,14 +53,6 @@ <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </dependency> - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-databind</artifactId> - </dependency> - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-annotations</artifactId> - </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-http/src/main/java/org/apache/tika/pipes/fetcher/http/config/HttpFetcherConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-http/src/main/java/org/apache/tika/pipes/fetcher/http/config/HttpFetcherConfig.java index 68efc2f69f..9c3f9833ae 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-http/src/main/java/org/apache/tika/pipes/fetcher/http/config/HttpFetcherConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-http/src/main/java/org/apache/tika/pipes/fetcher/http/config/HttpFetcherConfig.java @@ -23,10 +23,11 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; +import org.apache.tika.plugins.PluginJson; public class HttpFetcherConfig { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static HttpFetcherConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/java/org/apache/tika/pipes/emitter/jdbc/JDBCEmitterConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/java/org/apache/tika/pipes/emitter/jdbc/JDBCEmitterConfig.java index 0b6aeab38d..a1a31f770d 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/java/org/apache/tika/pipes/emitter/jdbc/JDBCEmitterConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/java/org/apache/tika/pipes/emitter/jdbc/JDBCEmitterConfig.java @@ -23,6 +23,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; +import org.apache.tika.plugins.PluginJson; public record JDBCEmitterConfig( String connection, @@ -59,7 +60,7 @@ public record JDBCEmitterConfig( FIRST_ONLY, CONCATENATE } - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static JDBCEmitterConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/java/org/apache/tika/pipes/iterator/jdbc/JDBCPipesIteratorConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/java/org/apache/tika/pipes/iterator/jdbc/JDBCPipesIteratorConfig.java index ff6b68d229..6b371d14e2 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/java/org/apache/tika/pipes/iterator/jdbc/JDBCPipesIteratorConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/java/org/apache/tika/pipes/iterator/jdbc/JDBCPipesIteratorConfig.java @@ -23,10 +23,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; import org.apache.tika.pipes.pipesiterator.PipesIteratorConfig; +import org.apache.tika.plugins.PluginJson; public class JDBCPipesIteratorConfig extends PipesIteratorConfig { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static JDBCPipesIteratorConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/java/org/apache/tika/pipes/reporter/jdbc/JDBCPipesReporterConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/java/org/apache/tika/pipes/reporter/jdbc/JDBCPipesReporterConfig.java index 94a7df3dc1..f3e0144a9f 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/java/org/apache/tika/pipes/reporter/jdbc/JDBCPipesReporterConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/java/org/apache/tika/pipes/reporter/jdbc/JDBCPipesReporterConfig.java @@ -25,6 +25,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; +import org.apache.tika.plugins.PluginJson; /** * @@ -50,7 +51,7 @@ public record JDBCPipesReporterConfig(String connectionString, Set<String> inclu String postConnectionSql, List<String> reportVariables, long reportWithinMs, int cacheSize) { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static JDBCPipesReporterConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-json/src/main/java/org/apache/tika/pipes/pipesiterator/json/JsonPipesIteratorConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-json/src/main/java/org/apache/tika/pipes/pipesiterator/json/JsonPipesIteratorConfig.java index c3f6f53924..f4014c7c01 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-json/src/main/java/org/apache/tika/pipes/pipesiterator/json/JsonPipesIteratorConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-json/src/main/java/org/apache/tika/pipes/pipesiterator/json/JsonPipesIteratorConfig.java @@ -24,10 +24,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; import org.apache.tika.pipes.pipesiterator.PipesIteratorConfig; +import org.apache.tika.plugins.PluginJson; public class JsonPipesIteratorConfig extends PipesIteratorConfig { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static JsonPipesIteratorConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-kafka/pom.xml b/tika-pipes/tika-pipes-plugins/tika-pipes-kafka/pom.xml index 108cf10b03..a460674d01 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-kafka/pom.xml +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-kafka/pom.xml @@ -35,11 +35,6 @@ <version>${project.version}</version> <scope>provided</scope> </dependency> - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-databind</artifactId> - <scope>provided</scope> - </dependency> <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-clients</artifactId> diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-kafka/src/main/java/org/apache/tika/pipes/emitter/kafka/KafkaEmitterConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-kafka/src/main/java/org/apache/tika/pipes/emitter/kafka/KafkaEmitterConfig.java index ba952c91e3..26d043870c 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-kafka/src/main/java/org/apache/tika/pipes/emitter/kafka/KafkaEmitterConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-kafka/src/main/java/org/apache/tika/pipes/emitter/kafka/KafkaEmitterConfig.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; +import org.apache.tika.plugins.PluginJson; /** Boxed: an unset value stays null so safePut omits the property and Kafka applies its own default. */ public record KafkaEmitterConfig( @@ -48,7 +49,7 @@ public record KafkaEmitterConfig( String valueSerializer ) { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static KafkaEmitterConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-kafka/src/main/java/org/apache/tika/pipes/iterator/kafka/KafkaPipesIteratorConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-kafka/src/main/java/org/apache/tika/pipes/iterator/kafka/KafkaPipesIteratorConfig.java index e962a5c568..f036b31611 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-kafka/src/main/java/org/apache/tika/pipes/iterator/kafka/KafkaPipesIteratorConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-kafka/src/main/java/org/apache/tika/pipes/iterator/kafka/KafkaPipesIteratorConfig.java @@ -23,10 +23,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; import org.apache.tika.pipes.pipesiterator.PipesIteratorConfig; +import org.apache.tika.plugins.PluginJson; public class KafkaPipesIteratorConfig extends PipesIteratorConfig { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static KafkaPipesIteratorConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-microsoft-graph/src/main/java/org/apache/tika/pipes/fetchers/microsoftgraph/config/MicrosoftGraphFetcherConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-microsoft-graph/src/main/java/org/apache/tika/pipes/fetchers/microsoftgraph/config/MicrosoftGraphFetcherConfig.java index c4e8fd0bda..7f1adb2931 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-microsoft-graph/src/main/java/org/apache/tika/pipes/fetchers/microsoftgraph/config/MicrosoftGraphFetcherConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-microsoft-graph/src/main/java/org/apache/tika/pipes/fetchers/microsoftgraph/config/MicrosoftGraphFetcherConfig.java @@ -23,10 +23,11 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; +import org.apache.tika.plugins.PluginJson; public class MicrosoftGraphFetcherConfig { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static MicrosoftGraphFetcherConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-opensearch/src/main/java/org/apache/tika/pipes/emitter/opensearch/HttpClientConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-opensearch/src/main/java/org/apache/tika/pipes/emitter/opensearch/HttpClientConfig.java index ddd5e7b5c2..976377aea5 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-opensearch/src/main/java/org/apache/tika/pipes/emitter/opensearch/HttpClientConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-opensearch/src/main/java/org/apache/tika/pipes/emitter/opensearch/HttpClientConfig.java @@ -20,6 +20,8 @@ import java.io.IOException; import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.tika.plugins.PluginJson; + /** * @param verifySsl When {@code true} (the default), the HTTP client validates server certificates @@ -31,7 +33,7 @@ public record HttpClientConfig(String userName, String password, String authScheme, int connectionTimeoutMillis, int socketTimeoutMillis, String proxyHost, int proxyPort, Boolean verifySsl) { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static HttpClientConfig load(final String json) throws IOException { return OBJECT_MAPPER.readValue(json, HttpClientConfig.class); } diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-opensearch/src/main/java/org/apache/tika/pipes/emitter/opensearch/OpenSearchEmitterConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-opensearch/src/main/java/org/apache/tika/pipes/emitter/opensearch/OpenSearchEmitterConfig.java index 6e4eb095f5..78a4943f62 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-opensearch/src/main/java/org/apache/tika/pipes/emitter/opensearch/OpenSearchEmitterConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-opensearch/src/main/java/org/apache/tika/pipes/emitter/opensearch/OpenSearchEmitterConfig.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; +import org.apache.tika.plugins.PluginJson; public record OpenSearchEmitterConfig(String openSearchUrl, String idField, AttachmentStrategy attachmentStrategy, UpdateStrategy updateStrategy, int commitWithin, @@ -32,7 +33,7 @@ public record OpenSearchEmitterConfig(String openSearchUrl, String idField, Atta OVERWRITE, UPSERT } - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static OpenSearchEmitterConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-opensearch/src/main/java/org/apache/tika/pipes/reporter/opensearch/HttpClientConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-opensearch/src/main/java/org/apache/tika/pipes/reporter/opensearch/HttpClientConfig.java index bed1db04eb..48ed8ca5b4 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-opensearch/src/main/java/org/apache/tika/pipes/reporter/opensearch/HttpClientConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-opensearch/src/main/java/org/apache/tika/pipes/reporter/opensearch/HttpClientConfig.java @@ -20,6 +20,8 @@ import java.io.IOException; import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.tika.plugins.PluginJson; + /** * @param verifySsl When {@code true} (the default), the HTTP client validates server certificates @@ -31,7 +33,7 @@ public record HttpClientConfig(String userName, String password, String authScheme, int connectionTimeoutMillis, int socketTimeoutMillis, String proxyHost, int proxyPort, Boolean verifySsl) { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static HttpClientConfig load(final String json) throws IOException { return OBJECT_MAPPER.readValue(json, HttpClientConfig.class); } diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-opensearch/src/main/java/org/apache/tika/pipes/reporter/opensearch/OpenSearchReporterConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-opensearch/src/main/java/org/apache/tika/pipes/reporter/opensearch/OpenSearchReporterConfig.java index a787fc3019..991ba3f24d 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-opensearch/src/main/java/org/apache/tika/pipes/reporter/opensearch/OpenSearchReporterConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-opensearch/src/main/java/org/apache/tika/pipes/reporter/opensearch/OpenSearchReporterConfig.java @@ -22,11 +22,12 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; +import org.apache.tika.plugins.PluginJson; public record OpenSearchReporterConfig(String openSearchUrl, Set<String> includes, Set<String> excludes, String keyPrefix, boolean includeRouting, HttpClientConfig httpClientConfig) { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static OpenSearchReporterConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/pom.xml b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/pom.xml index f51eeeb21a..dd757617f1 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/pom.xml +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/pom.xml @@ -41,11 +41,6 @@ <version>${project.version}</version> <scope>provided</scope> </dependency> - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-databind</artifactId> - <scope>provided</scope> - </dependency> <dependency> <groupId>software.amazon.awssdk</groupId> <artifactId>s3</artifactId> diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/emitter/s3/S3EmitterConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/emitter/s3/S3EmitterConfig.java index e3174aaba4..91baa5b146 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/emitter/s3/S3EmitterConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/emitter/s3/S3EmitterConfig.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; +import org.apache.tika.plugins.PluginJson; public record S3EmitterConfig( String region, @@ -56,7 +57,7 @@ public record S3EmitterConfig( } } - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static S3EmitterConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/fetcher/s3/config/S3FetcherConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/fetcher/s3/config/S3FetcherConfig.java index ff44338428..193d20b423 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/fetcher/s3/config/S3FetcherConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/fetcher/s3/config/S3FetcherConfig.java @@ -20,10 +20,11 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; +import org.apache.tika.plugins.PluginJson; public class S3FetcherConfig { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static S3FetcherConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/iterator/s3/S3PipesIteratorConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/iterator/s3/S3PipesIteratorConfig.java index 4e8cf3ef20..eb74db5998 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/iterator/s3/S3PipesIteratorConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/iterator/s3/S3PipesIteratorConfig.java @@ -23,10 +23,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; import org.apache.tika.pipes.pipesiterator.PipesIteratorConfig; +import org.apache.tika.plugins.PluginJson; public class S3PipesIteratorConfig extends PipesIteratorConfig { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static S3PipesIteratorConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-solr/pom.xml b/tika-pipes/tika-pipes-plugins/tika-pipes-solr/pom.xml index ea7059a9db..c7cb52664d 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-solr/pom.xml +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-solr/pom.xml @@ -67,10 +67,6 @@ <artifactId>solr-solrj-zookeeper</artifactId> <version>${solrj.version}</version> </dependency> - <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-databind</artifactId> - </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-solr/src/main/java/org/apache/tika/pipes/emitter/solr/SolrEmitterConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-solr/src/main/java/org/apache/tika/pipes/emitter/solr/SolrEmitterConfig.java index 8fda64a7b5..ecdffd5358 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-solr/src/main/java/org/apache/tika/pipes/emitter/solr/SolrEmitterConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-solr/src/main/java/org/apache/tika/pipes/emitter/solr/SolrEmitterConfig.java @@ -24,6 +24,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; +import org.apache.tika.plugins.PluginJson; public record SolrEmitterConfig( String solrCollection, @@ -53,7 +54,7 @@ public record SolrEmitterConfig( ADD, UPDATE_MUST_EXIST, UPDATE_MUST_NOT_EXIST } - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static SolrEmitterConfig load(final String json) throws TikaConfigException { diff --git a/tika-pipes/tika-pipes-plugins/tika-pipes-solr/src/main/java/org/apache/tika/pipes/iterator/solr/SolrPipesIteratorConfig.java b/tika-pipes/tika-pipes-plugins/tika-pipes-solr/src/main/java/org/apache/tika/pipes/iterator/solr/SolrPipesIteratorConfig.java index 0764bf21d8..a442c103ba 100644 --- a/tika-pipes/tika-pipes-plugins/tika-pipes-solr/src/main/java/org/apache/tika/pipes/iterator/solr/SolrPipesIteratorConfig.java +++ b/tika-pipes/tika-pipes-plugins/tika-pipes-solr/src/main/java/org/apache/tika/pipes/iterator/solr/SolrPipesIteratorConfig.java @@ -25,10 +25,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.tika.exception.TikaConfigException; import org.apache.tika.pipes.pipesiterator.PipesIteratorConfig; +import org.apache.tika.plugins.PluginJson; public class SolrPipesIteratorConfig extends PipesIteratorConfig { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final ObjectMapper OBJECT_MAPPER = PluginJson.mapper(); public static SolrPipesIteratorConfig load(final String json) throws TikaConfigException { diff --git a/tika-plugins-core/src/main/java/org/apache/tika/plugins/PluginJson.java b/tika-plugins-core/src/main/java/org/apache/tika/plugins/PluginJson.java new file mode 100644 index 0000000000..faca63283f --- /dev/null +++ b/tika-plugins-core/src/main/java/org/apache/tika/plugins/PluginJson.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.tika.plugins; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; + +import org.apache.tika.exception.TikaConfigException; + +/** + * The one {@link ObjectMapper} for plugin configuration JSON ({@link ExtensionConfig#json()}). + * <p> + * Fails fast on what a hand-written config gets wrong: unknown keys, a number where an + * enum name belongs, duplicate keys. Comments are + * accepted, as in the main config loader. Plain JSON only -- no Tika component serializers + * -- so it is safe to share across the plugin classloader boundary, provided the plugin + * does not bundle its own Jackson (the plugins parent pom enforces that). + */ +public final class PluginJson { + + private static final ObjectMapper MAPPER = new ObjectMapper() + .enable(JsonParser.Feature.ALLOW_COMMENTS) + // parser-level: FAIL_ON_READING_DUP_TREE_KEY only covers readTree, not readValue + .enable(JsonParser.Feature.STRICT_DUPLICATE_DETECTION) + .enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + // Not FAIL_ON_NULL_FOR_PRIMITIVES: it also fires for a primitive record component + // that is simply absent, and optional primitives with defaults are the norm here. + .enable(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS) + .disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); + + private PluginJson() { + } + + /** Shared and immutable in practice: callers must not reconfigure it. */ + public static ObjectMapper mapper() { + return MAPPER; + } + + /** Deserializes {@code json} into {@code type}, reporting failures as config errors. */ + public static <T> T read(String json, Class<T> type) throws TikaConfigException { + try { + return MAPPER.readValue(json, type); + } catch (JsonProcessingException e) { + throw new TikaConfigException( + "Failed to parse " + type.getSimpleName() + ": " + e.getOriginalMessage(), e); + } + } +} diff --git a/tika-plugins-core/src/test/java/org/apache/tika/plugins/PluginJsonTest.java b/tika-plugins-core/src/test/java/org/apache/tika/plugins/PluginJsonTest.java new file mode 100644 index 0000000000..b6be710d2f --- /dev/null +++ b/tika-plugins-core/src/test/java/org/apache/tika/plugins/PluginJsonTest.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.tika.plugins; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +import org.apache.tika.exception.TikaConfigException; + +public class PluginJsonTest { + + enum Mode { FAST, SLOW } + + public record Sample(String name, long count, Mode mode) { } + + public static class Bean { + private int size; + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + } + + @Test + public void testCommentsAccepted() throws Exception { + Sample s = PluginJson.read(""" + // leading + { /* block */ "name": "a", "count": 2, "mode": "FAST" } // trailing + """, Sample.class); + assertEquals(new Sample("a", 2, Mode.FAST), s); + } + + @Test + public void testRejected() { + String[] cases = { + "{\"name\":\"a\",\"count\":2,\"mode\":\"FAST\",\"typo\":1}", // unknown key + "{\"name\":\"a\",\"count\":2,\"mode\":0}", // numeric enum + "{\"name\":\"a\",\"count\":2,\"count\":3,\"mode\":\"FAST\"}" // duplicate key + }; + for (String json : cases) { + TikaConfigException e = assertThrows(TikaConfigException.class, + () -> PluginJson.read(json, Sample.class), json); + assertTrue(e.getMessage().startsWith("Failed to parse Sample"), e.getMessage()); + } + } + + @Test + public void testMissingPrimitiveTakesDefault() throws Exception { + // Optional primitives are the norm in plugin configs; absence must not be an error. + assertEquals(0, PluginJson.read("{\"name\":\"a\",\"mode\":\"SLOW\"}", Sample.class).count()); + } + + @Test + public void testDuplicateKeyRejectedForBeans() { + // Bean setters would silently take the last value without STRICT_DUPLICATE_DETECTION. + assertThrows(TikaConfigException.class, + () -> PluginJson.read("{\"size\":1,\"size\":2}", Bean.class)); + } +}
