This is an automated email from the ASF dual-hosted git repository.
tballison pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tika.git
The following commit(s) were added to refs/heads/main by this push:
new f1645e6e55 TIKA-4840: host-provided Jackson for pipes plugins; one
strict Plugin… (#3066)
f1645e6e55 is described below
commit f1645e6e55332839fcb866a117b07e82ed506ac9
Author: Tim Allison <[email protected]>
AuthorDate: Tue Aug 25 20:38:29 2026 -0400
TIKA-4840: host-provided Jackson for pipes plugins; one strict Plugin…
(#3066)
---
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 | 13 +---
.../tika-pipes-plugins/tika-pipes-az-blob/pom.xml | 4 --
.../pipes/emitter/azblob/AZBlobEmitterConfig.java | 12 +---
.../fetcher/azblob/config/AZBlobFetcherConfig.java | 13 +---
.../iterator/azblob/AZBlobPipesIteratorConfig.java | 14 +---
.../pipes/iterator/csv/CSVPipesIteratorConfig.java | 14 +---
.../tika/pipes/emitter/es/ESEmitterConfig.java | 13 +---
.../tika/pipes/reporter/es/ESReporterConfig.java | 14 +---
.../tika-pipes-file-system/pom.xml | 5 --
.../pipes/emitter/fs/FileSystemEmitterConfig.java | 14 +---
.../emitter/fs/FileSystemEmitterRuntimeConfig.java | 14 +---
.../pipes/fetcher/fs/FileSystemFetcherConfig.java | 14 +---
.../iterator/fs/FileSystemPipesIteratorConfig.java | 15 +---
.../reporter/fs/FileSystemReporterConfig.java | 14 +---
.../pipes/fetcher/fs/FileSystemFetcherTest.java | 13 ++++
.../tika/pipes/emitter/gcs/GCSEmitterConfig.java | 12 +---
.../pipes/fetcher/gcs/config/GCSFetcherConfig.java | 13 +---
.../pipes/iterator/gcs/GCSPipesIteratorConfig.java | 13 +---
.../tika-pipes-google-drive/pom.xml | 8 ---
.../config/GoogleDriveFetcherConfig.java | 13 +---
.../tika-pipes-plugins/tika-pipes-http/pom.xml | 8 ---
.../fetcher/http/config/HttpFetcherConfig.java | 13 +---
.../tika/pipes/emitter/jdbc/JDBCEmitterConfig.java | 13 +---
.../iterator/jdbc/JDBCPipesIteratorConfig.java | 14 +---
.../reporter/jdbc/JDBCPipesReporterConfig.java | 13 +---
.../json/JsonPipesIteratorConfig.java | 14 +---
.../tika-pipes-plugins/tika-pipes-kafka/pom.xml | 5 --
.../pipes/emitter/kafka/KafkaEmitterConfig.java | 13 +---
.../iterator/kafka/KafkaPipesIteratorConfig.java | 14 +---
.../config/MicrosoftGraphFetcherConfig.java | 15 +---
.../pipes/emitter/opensearch/HttpClientConfig.java | 10 ---
.../opensearch/OpenSearchEmitterConfig.java | 14 +---
.../reporter/opensearch/HttpClientConfig.java | 10 ---
.../opensearch/OpenSearchReporterConfig.java | 14 +---
.../tika-pipes-plugins/tika-pipes-s3/pom.xml | 5 --
.../tika/pipes/emitter/s3/S3EmitterConfig.java | 13 +---
.../pipes/fetcher/s3/config/S3FetcherConfig.java | 13 +---
.../pipes/iterator/s3/S3PipesIteratorConfig.java | 13 +---
.../tika-pipes-plugins/tika-pipes-solr/pom.xml | 4 --
.../tika/pipes/emitter/solr/SolrEmitterConfig.java | 12 +---
.../iterator/solr/SolrPipesIteratorConfig.java | 14 +---
.../java/org/apache/tika/plugins/PluginJson.java | 60 ++++++++++++++++
.../org/apache/tika/plugins/PluginJsonTest.java | 80 ++++++++++++++++++++++
47 files changed, 269 insertions(+), 425 deletions(-)
diff --git a/CHANGES.txt b/CHANGES.txt
index 7764f16272..9b7edca602 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).
+
* tika-server and tika-async-cli now start from a config that contains
// or /* */ comments, as the configuration docs have always said they
may. The main loader accepted them; the steps that re-read the user's
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 86b356151e..ffa2818d2e 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..a01ce7d5c8 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
@@ -21,23 +21,14 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-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();
-
public static AtlassianJwtFetcherConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json,
AtlassianJwtFetcherConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse AtlassianJwtFetcherConfig from JSON", e);
- }
+ return PluginJson.read(json, AtlassianJwtFetcherConfig.class);
}
private Integer maxConnectionsPerRoute = 1000;
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 52d1dd10a5..d2cfbe78ea 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..d7cfdecaa0 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
@@ -17,10 +17,9 @@
package org.apache.tika.pipes.emitter.azblob;
import com.fasterxml.jackson.annotation.JsonProperty;
-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,16 +30,9 @@ public record AZBlobEmitterConfig(
@JsonProperty(defaultValue = "false") boolean overwriteExisting
) {
- private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
-
public static AZBlobEmitterConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json, AZBlobEmitterConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse AZBlobEmitterConfig from JSON", e);
- }
+ return PluginJson.read(json, AZBlobEmitterConfig.class);
}
public void validate() 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..3c715ea82a 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
@@ -16,23 +16,14 @@
*/
package org.apache.tika.pipes.fetcher.azblob.config;
-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();
-
public static AZBlobFetcherConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json, AZBlobFetcherConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse AZBlobFetcherConfig from JSON", e);
- }
+ return PluginJson.read(json, AZBlobFetcherConfig.class);
}
private boolean spoolToTemp = true;
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..ff91674740 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
@@ -18,25 +18,15 @@ package org.apache.tika.pipes.iterator.azblob;
import java.util.Objects;
-import com.fasterxml.jackson.core.JsonProcessingException;
-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();
-
public static AZBlobPipesIteratorConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json,
- AZBlobPipesIteratorConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse AZBlobPipesIteratorConfig from JSON", e);
- }
+ return PluginJson.read(json, AZBlobPipesIteratorConfig.class);
}
private String sasToken;
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..2e963799a2 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
@@ -19,25 +19,15 @@ package org.apache.tika.pipes.iterator.csv;
import java.nio.file.Path;
import java.util.Objects;
-import com.fasterxml.jackson.core.JsonProcessingException;
-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();
-
public static CSVPipesIteratorConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json,
- CSVPipesIteratorConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse CSVPipesIteratorConfig from JSON", e);
- }
+ return PluginJson.read(json, CSVPipesIteratorConfig.class);
}
private Path csvPath;
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..a68eb7c4cf 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
@@ -16,10 +16,8 @@
*/
package org.apache.tika.pipes.emitter.es;
-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,16 +47,9 @@ public record ESEmitterConfig(String esUrl, String idField,
OVERWRITE, UPSERT
}
- private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
-
public static ESEmitterConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json, ESEmitterConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse ESEmitterConfig from JSON", e);
- }
+ return PluginJson.read(json, ESEmitterConfig.class);
}
/** Overrides the record default to prevent {@code apiKey} leaking into
logs. */
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..1507f5aeeb 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
@@ -18,28 +18,18 @@ package org.apache.tika.pipes.reporter.es;
import java.util.Set;
-import com.fasterxml.jackson.core.JsonProcessingException;
-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();
-
public static ESReporterConfig load(final String json) throws
TikaConfigException {
- ESReporterConfig config;
- try {
- config = OBJECT_MAPPER.readValue(json, ESReporterConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse ESReporterConfig from JSON", e);
- }
+ ESReporterConfig config = PluginJson.read(json,
ESReporterConfig.class);
// keyPrefix is prepended to this reporter's own scratch-Metadata keys
(parse_status/
// parse_time_ms/exit_value); reject a reserved prefix here, before it
fails every report() call.
if (!StringUtils.isBlank(config.keyPrefix()) &&
ReservedNamespaces.isTikaNative(config.keyPrefix())) {
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 fde5070d52..06d1602e00 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..7fc17e2d84 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
@@ -16,10 +16,8 @@
*/
package org.apache.tika.pipes.emitter.fs;
-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,17 +32,9 @@ public record FileSystemEmitterConfig(String basePath,
String fileExtension, ON_
}
}
- private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
-
public static FileSystemEmitterConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json,
- FileSystemEmitterConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse FileSystemEmitterConfig from JSON", e);
- }
+ return PluginJson.read(json, FileSystemEmitterConfig.class);
}
}
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..2ceffcea01 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
@@ -16,10 +16,8 @@
*/
package org.apache.tika.pipes.emitter.fs;
-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,17 +26,9 @@ import org.apache.tika.exception.TikaConfigException;
*/
public class FileSystemEmitterRuntimeConfig {
- private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
-
public static FileSystemEmitterRuntimeConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json,
- FileSystemEmitterRuntimeConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse FileSystemEmitterRuntimeConfig from
JSON", e);
- }
+ return PluginJson.read(json, FileSystemEmitterRuntimeConfig.class);
}
private String fileExtension;
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..6abb55f547 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
@@ -16,24 +16,14 @@
*/
package org.apache.tika.pipes.fetcher.fs;
-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();
-
public static FileSystemFetcherConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json,
- FileSystemFetcherConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse FileSystemFetcherConfig from JSON", e);
- }
+ return PluginJson.read(json, FileSystemFetcherConfig.class);
}
private String basePath;
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..7756fccf85 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
@@ -19,26 +19,15 @@ package org.apache.tika.pipes.iterator.fs;
import java.nio.file.Path;
import java.util.Objects;
-import com.fasterxml.jackson.core.JsonProcessingException;
-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();
-
public static FileSystemPipesIteratorConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json,
- FileSystemPipesIteratorConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse FileSystemPipesIteratorConfig from JSON",
- e);
- }
+ return PluginJson.read(json, FileSystemPipesIteratorConfig.class);
}
private Path basePath = null;
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..42fe953599 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
@@ -19,23 +19,13 @@ package org.apache.tika.pipes.reporter.fs;
import java.io.Serializable;
import java.nio.file.Path;
-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();
-
public static FileSystemReporterConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json,
- FileSystemReporterConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse FileSystemReporterConfig from JSON", e);
- }
+ return PluginJson.read(json, FileSystemReporterConfig.class);
}
}
diff --git
a/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/test/java/org/apache/tika/pipes/fetcher/fs/FileSystemFetcherTest.java
b/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/test/java/org/apache/tika/pipes/fetcher/fs/FileSystemFetcherTest.java
index 1a30b8c429..eadaa33281 100644
---
a/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/test/java/org/apache/tika/pipes/fetcher/fs/FileSystemFetcherTest.java
+++
b/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/test/java/org/apache/tika/pipes/fetcher/fs/FileSystemFetcherTest.java
@@ -18,6 +18,7 @@ package org.apache.tika.pipes.fetcher.fs;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.nio.file.Files;
@@ -139,4 +140,16 @@ public class FileSystemFetcherTest {
assertNotNull(tis);
}
}
+
+ @Test
+ public void testUnknownKeyRejected() {
+ // guards the plugin actually parsing through PluginJson, not a
lenient mapper
+ ObjectNode config = MAPPER.createObjectNode();
+ config.put("basePath", tempDir.toAbsolutePath().toString());
+ config.put("basePaht", "x");
+ ExtensionConfig pluginConfig = new ExtensionConfig("test", "test",
config.toString());
+ TikaConfigException e = assertThrows(TikaConfigException.class,
+ () -> new
FileSystemFetcherFactory().buildExtension(pluginConfig));
+ assertTrue(e.getMessage().contains("basePaht"), e.getMessage());
+ }
}
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..a7408ba4b3 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
@@ -17,10 +17,9 @@
package org.apache.tika.pipes.emitter.gcs;
import com.fasterxml.jackson.annotation.JsonProperty;
-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,16 +28,9 @@ public record GCSEmitterConfig(
@JsonProperty(defaultValue = "json") String fileExtension
) {
- private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
-
public static GCSEmitterConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json, GCSEmitterConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse GCSEmitterConfig from JSON", e);
- }
+ return PluginJson.read(json, GCSEmitterConfig.class);
}
public void validate() 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..d739a07c55 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
@@ -16,23 +16,14 @@
*/
package org.apache.tika.pipes.fetcher.gcs.config;
-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();
-
public static GCSFetcherConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json, GCSFetcherConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse GCSFetcherConfig from JSON", e);
- }
+ return PluginJson.read(json, GCSFetcherConfig.class);
}
private boolean spoolToTemp = true;
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..9244dd7565 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
@@ -18,24 +18,15 @@ package org.apache.tika.pipes.iterator.gcs;
import java.util.Objects;
-import com.fasterxml.jackson.core.JsonProcessingException;
-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();
-
public static GCSPipesIteratorConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json, GCSPipesIteratorConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse GCSPipesIteratorConfig from JSON", e);
- }
+ return PluginJson.read(json, GCSPipesIteratorConfig.class);
}
private String bucket;
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 55483a6f1b..b3926c236f 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..b1dba81253 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
@@ -19,23 +19,14 @@ package org.apache.tika.pipes.fetcher.googledrive.config;
import java.util.ArrayList;
import java.util.List;
-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();
-
public static GoogleDriveFetcherConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json,
GoogleDriveFetcherConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse GoogleDriveFetcherConfig from JSON", e);
- }
+ return PluginJson.read(json, GoogleDriveFetcherConfig.class);
}
private List<Long> throttleSeconds;
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 d716a37f9d..92337e4eba 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..bcf5e0a22c 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
@@ -19,23 +19,14 @@ package org.apache.tika.pipes.fetcher.http.config;
import java.util.ArrayList;
import java.util.List;
-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();
-
public static HttpFetcherConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json, HttpFetcherConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse HttpFetcherConfig from JSON", e);
- }
+ return PluginJson.read(json, HttpFetcherConfig.class);
}
private String userName;
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..f8bb48cb5f 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
@@ -19,10 +19,8 @@ package org.apache.tika.pipes.emitter.jdbc;
import java.util.LinkedHashMap;
import java.util.Locale;
-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,16 +57,9 @@ public record JDBCEmitterConfig(
FIRST_ONLY, CONCATENATE
}
- private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
-
public static JDBCEmitterConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json, JDBCEmitterConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse JDBCEmitterConfig from JSON", e);
- }
+ return PluginJson.read(json, JDBCEmitterConfig.class);
}
public void validate() 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..ab92160595 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
@@ -18,25 +18,15 @@ package org.apache.tika.pipes.iterator.jdbc;
import java.util.Objects;
-import com.fasterxml.jackson.core.JsonProcessingException;
-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();
-
public static JDBCPipesIteratorConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json,
- JDBCPipesIteratorConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse JDBCPipesIteratorConfig from JSON", e);
- }
+ return PluginJson.read(json, JDBCPipesIteratorConfig.class);
}
private String idColumn;
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..92ba2d3963 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
@@ -21,10 +21,9 @@ import java.util.Set;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
-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,17 +49,9 @@ 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();
-
public static JDBCPipesReporterConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json,
- JDBCPipesReporterConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse JDBCPipesReporterConfig from JSON", e);
- }
+ return PluginJson.read(json, JDBCPipesReporterConfig.class);
}
@JsonCreator
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..7574a724a0 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
@@ -19,25 +19,15 @@ package org.apache.tika.pipes.pipesiterator.json;
import java.nio.file.Path;
import java.util.Objects;
-import com.fasterxml.jackson.core.JsonProcessingException;
-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();
-
public static JsonPipesIteratorConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json,
- JsonPipesIteratorConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse JsonPipesIteratorConfig from JSON", e);
- }
+ return PluginJson.read(json, JsonPipesIteratorConfig.class);
}
private Path jsonPath;
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 37dd8dcb42..c3f5e729ba 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..9c34d911bc 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
@@ -16,10 +16,8 @@
*/
package org.apache.tika.pipes.emitter.kafka;
-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,16 +46,9 @@ public record KafkaEmitterConfig(
String valueSerializer
) {
- private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
-
public static KafkaEmitterConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json, KafkaEmitterConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse KafkaEmitterConfig from JSON", e);
- }
+ return PluginJson.read(json, KafkaEmitterConfig.class);
}
public void validate() 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..ff971ea613 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
@@ -18,25 +18,15 @@ package org.apache.tika.pipes.iterator.kafka;
import java.util.Objects;
-import com.fasterxml.jackson.core.JsonProcessingException;
-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();
-
public static KafkaPipesIteratorConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json,
- KafkaPipesIteratorConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse KafkaPipesIteratorConfig from JSON", e);
- }
+ return PluginJson.read(json, KafkaPipesIteratorConfig.class);
}
private String topic;
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..825632d685 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
@@ -19,25 +19,14 @@ package
org.apache.tika.pipes.fetchers.microsoftgraph.config;
import java.util.ArrayList;
import java.util.List;
-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();
-
public static MicrosoftGraphFetcherConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json,
- MicrosoftGraphFetcherConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse MicrosoftGraphFetcherConfig from JSON",
- e);
- }
+ return PluginJson.read(json, MicrosoftGraphFetcherConfig.class);
}
private long[] throttleSeconds;
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..daabfc0208 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
@@ -16,11 +16,6 @@
*/
package org.apache.tika.pipes.emitter.opensearch;
-import java.io.IOException;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-
/**
* @param verifySsl When {@code true} (the default), the HTTP client validates
server certificates
* and hostnames using the JVM's default trust store. Set
{@code false} to trust
@@ -31,11 +26,6 @@ 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();
- public static HttpClientConfig load(final String json) throws IOException {
- return OBJECT_MAPPER.readValue(json, HttpClientConfig.class);
- }
-
/** Boxed so an absent {@code verifySsl} is distinguishable from an
explicit {@code false}. */
public boolean verifySslOrDefault() {
return verifySsl == null || verifySsl;
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..660885d76d 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
@@ -16,10 +16,8 @@
*/
package org.apache.tika.pipes.emitter.opensearch;
-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,17 +30,9 @@ public record OpenSearchEmitterConfig(String openSearchUrl,
String idField, Atta
OVERWRITE, UPSERT
}
- private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
-
public static OpenSearchEmitterConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json,
- OpenSearchEmitterConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse OpenSearchEmitterConfig from JSON", e);
- }
+ return PluginJson.read(json, OpenSearchEmitterConfig.class);
}
}
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..eb20a938a7 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
@@ -16,11 +16,6 @@
*/
package org.apache.tika.pipes.reporter.opensearch;
-import java.io.IOException;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-
/**
* @param verifySsl When {@code true} (the default), the HTTP client validates
server certificates
* and hostnames using the JVM's default trust store. Set
{@code false} to trust
@@ -31,11 +26,6 @@ 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();
- public static HttpClientConfig load(final String json) throws IOException {
- return OBJECT_MAPPER.readValue(json, HttpClientConfig.class);
- }
-
/** Boxed so an absent {@code verifySsl} is distinguishable from an
explicit {@code false}. */
public boolean verifySslOrDefault() {
return verifySsl == null || verifySsl;
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..1db7abbafc 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
@@ -18,25 +18,15 @@ package org.apache.tika.pipes.reporter.opensearch;
import java.util.Set;
-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();
-
public static OpenSearchReporterConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json,
- OpenSearchReporterConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse OpenSearchReporterConfig from JSON", e);
- }
+ return PluginJson.read(json, OpenSearchReporterConfig.class);
}
}
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 e8ffb28c75..8e29cb73a2 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..868f46cc53 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
@@ -16,10 +16,8 @@
*/
package org.apache.tika.pipes.emitter.s3;
-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,16 +54,9 @@ public record S3EmitterConfig(
}
}
- private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
-
public static S3EmitterConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json, S3EmitterConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse S3EmitterConfig from JSON", e);
- }
+ return PluginJson.read(json, S3EmitterConfig.class);
}
public void validate() 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..691b28698b 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
@@ -16,23 +16,14 @@
*/
package org.apache.tika.pipes.fetcher.s3.config;
-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();
-
public static S3FetcherConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json, S3FetcherConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse S3FetcherConfig from JSON", e);
- }
+ return PluginJson.read(json, S3FetcherConfig.class);
}
private boolean spoolToTemp = true;
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..b92a059c1b 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
@@ -18,24 +18,15 @@ package org.apache.tika.pipes.iterator.s3;
import java.util.Objects;
-import com.fasterxml.jackson.core.JsonProcessingException;
-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();
-
public static S3PipesIteratorConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json, S3PipesIteratorConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse S3PipesIteratorConfig from JSON", e);
- }
+ return PluginJson.read(json, S3PipesIteratorConfig.class);
}
private String prefix = "";
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 62ba948860..8d7f2648fb 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..5d5b5643b9 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
@@ -20,10 +20,9 @@ import java.util.List;
import java.util.Locale;
import com.fasterxml.jackson.annotation.JsonProperty;
-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,16 +52,9 @@ public record SolrEmitterConfig(
ADD, UPDATE_MUST_EXIST, UPDATE_MUST_NOT_EXIST
}
- private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
-
public static SolrEmitterConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json, SolrEmitterConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse SolrEmitterConfig from JSON", e);
- }
+ return PluginJson.read(json, SolrEmitterConfig.class);
}
public void validate() 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..5043a534a0 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
@@ -20,25 +20,15 @@ import java.util.Collections;
import java.util.List;
import java.util.Objects;
-import com.fasterxml.jackson.core.JsonProcessingException;
-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();
-
public static SolrPipesIteratorConfig load(final String json)
throws TikaConfigException {
- try {
- return OBJECT_MAPPER.readValue(json,
- SolrPipesIteratorConfig.class);
- } catch (JsonProcessingException e) {
- throw new TikaConfigException(
- "Failed to parse SolrPipesIteratorConfig from JSON", e);
- }
+ return PluginJson.read(json, SolrPipesIteratorConfig.class);
}
private String solrCollection;
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..03d9093add
--- /dev/null
+++ b/tika-plugins-core/src/main/java/org/apache/tika/plugins/PluginJson.java
@@ -0,0 +1,60 @@
+/*
+ * 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() {
+ }
+
+ /** 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));
+ }
+}