This is an automated email from the ASF dual-hosted git repository.

tballison pushed a commit to branch TIKA-4842
in repository https://gitbox.apache.org/repos/asf/tika.git

commit 1613479c1cfc1c08e4834e2c6be00a1e42d1b55b
Author: tallison <[email protected]>
AuthorDate: Wed Aug 26 11:57:11 2026 -0400

    TIKA-4842 - update docs and javadocs post 4.0.0 release
---
 CHANGES.txt                                            | 18 ++++++++++++++++++
 docs/modules/ROOT/pages/configuration/index.adoc       |  5 +++--
 .../ROOT/pages/configuration/metadata-filters.adoc     |  6 ++++--
 .../pages/configuration/parsers/tess4j-parser.adoc     |  5 ++++-
 docs/modules/ROOT/pages/developers/serialization.adoc  |  6 +++---
 .../ROOT/pages/maintainers/release-guides/tika.adoc    | 18 +++++++++---------
 docs/modules/ROOT/pages/migration-to-4x/index.adoc     |  4 ++--
 .../pages/migration-to-4x/metadata-changes-4x.adoc     |  4 +++-
 .../ROOT/pages/migration-to-4x/migrating-to-4x.adoc    |  9 ++++++---
 .../ROOT/pages/pipes/plugins/elasticsearch.adoc        |  4 ++--
 docs/modules/ROOT/pages/pipes/plugins/jdbc.adoc        |  2 +-
 docs/modules/ROOT/pages/pipes/plugins/kafka.adoc       |  4 ++--
 docs/modules/ROOT/pages/pipes/plugins/opensearch.adoc  |  4 ++--
 docs/modules/ROOT/pages/pipes/plugins/solr.adoc        |  6 ++++--
 .../ROOT/pages/pipes/plugins/writing-a-plugin.adoc     |  8 +++++---
 docs/modules/ROOT/pages/pipes/unpack-config.adoc       |  2 +-
 docs/modules/ROOT/pages/using-tika/docker.adoc         |  4 +++-
 tika-ml/tika-ml-junkdetect-tools/pom.xml               |  5 +++--
 .../tika/ml/junkdetect/JunkFilterEncodingDetector.java | 11 +++++------
 .../apache/tika/parser/ocr/tess4j/Tess4JConfig.java    |  7 ++++---
 .../org/apache/tika/parser/ocr/ImagePreprocessor.java  |  2 +-
 .../org/apache/tika/parser/ocr/TesseractOCRConfig.java |  4 ----
 .../atlassianjwt/AtlassianJwtFetcherFactory.java       |  4 ++--
 .../tika/pipes/emitter/azblob/AZBlobEmitter.java       |  4 ++--
 .../pipes/emitter/azblob/AZBlobEmitterFactory.java     |  4 ++--
 .../pipes/fetcher/azblob/AZBlobFetcherFactory.java     |  4 ++--
 .../apache/tika/pipes/emitter/es/ESEmitterFactory.java |  4 ++--
 .../pipes/emitter/fs/FileSystemEmitterFactory.java     |  4 ++--
 .../pipes/fetcher/fs/FileSystemFetcherFactory.java     |  4 ++--
 .../org/apache/tika/pipes/emitter/gcs/GCSEmitter.java  |  4 ++--
 .../tika/pipes/emitter/gcs/GCSEmitterFactory.java      |  4 ++--
 .../tika/pipes/fetcher/gcs/GCSFetcherFactory.java      |  4 ++--
 .../fetcher/googledrive/GoogleDriveFetcherFactory.java |  4 ++--
 .../tika/pipes/fetcher/http/HttpFetcherFactory.java    |  4 ++--
 .../apache/tika/pipes/emitter/jdbc/JDBCEmitter.java    |  4 ++--
 .../tika/pipes/emitter/jdbc/JDBCEmitterFactory.java    |  4 ++--
 .../apache/tika/pipes/emitter/kafka/KafkaEmitter.java  |  4 ++--
 .../tika/pipes/emitter/kafka/KafkaEmitterFactory.java  |  4 ++--
 .../microsoftgraph/MicrosoftGraphFetcherFactory.java   |  4 ++--
 .../emitter/opensearch/OpenSearchEmitterFactory.java   |  4 ++--
 .../org/apache/tika/pipes/emitter/s3/S3Emitter.java    |  4 ++--
 .../apache/tika/pipes/emitter/s3/S3EmitterFactory.java |  4 ++--
 .../apache/tika/pipes/fetcher/s3/S3FetcherFactory.java |  4 ++--
 .../apache/tika/pipes/emitter/solr/SolrEmitter.java    |  4 ++--
 .../tika/pipes/emitter/solr/SolrEmitterFactory.java    |  4 ++--
 45 files changed, 131 insertions(+), 99 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index 9b7edca602..c5ad109272 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,23 @@
 Release 4.1.0 - unreleased
 
+   * Documentation: corrected a batch of pages and javadocs that contradicted
+     the code. Notably: the ES/OpenSearch attachmentStrategy has no default
+     (unset means embedded documents get neither the parent field nor the
+     parent/child relation); Kafka's connectionsMaxIdleMs is passed to the
+     producer, not ignored; jdbc queryTimeoutSeconds is applied only when > 0,
+     so 0 does not mean "no limit"; the Solr emitter/iterator support only
+     basic auth, not ntlm, and only when a userName is set; pipes-reporters
+     silently loads zero reporters when given a JSON array, and
+     pipes-iterator/pipes-reporters instances are built at config load rather
+     than lazily; under CONTENT_ONLY only a parse-context filter replaces the
+     built-in one, not the top-level metadata-filters chain;
+     _mime-include/_mime-exclude also accept a bare string; Tess4J locks
+     poolSize and maxImagePixels as well as the two paths. Also corrected the
+     config nesting shown in every pipes-plugin fetcher/emitter javadoc -- 23
+     of them, which had it inverted (the instance id is the outer key, the
+     component name the inner) -- and removed references to a
+     TesseractOCRConfig.properties file that 4.x does not load (TIKA-4842).
+
    * 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
diff --git a/docs/modules/ROOT/pages/configuration/index.adoc 
b/docs/modules/ROOT/pages/configuration/index.adoc
index 0ddf7048e1..9d1407a603 100644
--- a/docs/modules/ROOT/pages/configuration/index.adoc
+++ b/docs/modules/ROOT/pages/configuration/index.adoc
@@ -81,8 +81,9 @@ produces no error and no effect:
   read;
 * the body of a self-configuring component under `parse-context` — it is 
handed to the component
   untouched;
-* `_mime-include` / `_mime-exclude` when the value is not a JSON array — a 
shape error yields an
-  empty filter rather than a failure;
+* `_mime-include` / `_mime-exclude` when the value is neither a JSON array nor 
a string — a bare
+  string is read as a one-element list, but any other shape yields an empty 
filter rather than a
+  failure;
 * a non-textual entry inside `default-parser`'s `exclude` list — the list 
expects plain strings,
   so an object or array entry such as `[{"pdf-parser": {}}]` is skipped and 
the component stays
   enabled. (An *unregistered name* in that list, and an unknown *key* in that 
same block, are
diff --git a/docs/modules/ROOT/pages/configuration/metadata-filters.adoc 
b/docs/modules/ROOT/pages/configuration/metadata-filters.adoc
index c6eee220fa..c7b1eeae30 100644
--- a/docs/modules/ROOT/pages/configuration/metadata-filters.adoc
+++ b/docs/modules/ROOT/pages/configuration/metadata-filters.adoc
@@ -235,8 +235,10 @@ one for that request rather than adding to it.
 
 NOTE: In `CONTENT_ONLY` xref:pipes/parse-modes.adoc[parse mode], Tika applies 
an
 `include-field-metadata-filter` for `tk:content` and 
`tk:exception:container-exception` when you have
-configured no filter of your own. Configure one and yours wins — including 
having to keep
-`tk:content` yourself.
+configured no filter of your own. Only a filter that reaches the 
`parse-context` replaces it —
+whether from the request or from the `parse-context` block of the server's own 
config — and then
+you are responsible for keeping `tk:content` yourself. The top-level 
`metadata-filters` chain this
+page documents is not consulted in this mode.
 
 == Writing your own
 
diff --git a/docs/modules/ROOT/pages/configuration/parsers/tess4j-parser.adoc 
b/docs/modules/ROOT/pages/configuration/parsers/tess4j-parser.adoc
index 3f37619dba..882abbbca4 100644
--- a/docs/modules/ROOT/pages/configuration/parsers/tess4j-parser.adoc
+++ b/docs/modules/ROOT/pages/configuration/parsers/tess4j-parser.adoc
@@ -273,4 +273,7 @@ context.set(Tess4JConfig.class, override);
 NOTE: In caller-supplied JSON config — the tika-server `/config` endpoints, 
tika-grpc's
 `parse_context_json` — `dataPath` and `nativeLibPath` are locked at parser 
initialization, and
 setting either throws `TikaConfigException`. They point at native code, so a 
caller must not be
-able to move them.
+able to move them. `poolSize` and `maxImagePixels` are locked in the same way 
but throw
+`IllegalStateException` -- for different reasons. The OCR pool is sized at 
initialization and
+cannot be resized per parse. `maxImagePixels` *is* read per parse, but it is 
the guard that
+bounds image decode against OOM, so a caller must not be able to raise it.
diff --git a/docs/modules/ROOT/pages/developers/serialization.adoc 
b/docs/modules/ROOT/pages/developers/serialization.adoc
index ecd0612424..35dde82a26 100644
--- a/docs/modules/ROOT/pages/developers/serialization.adoc
+++ b/docs/modules/ROOT/pages/developers/serialization.adoc
@@ -190,7 +190,7 @@ it needs it. `Parser` extends `SelfConfiguring`, so every 
parser is self-configu
 [source,java]
 ----
 @TikaComponent
-public class PDFParser implements Parser {
+public class PDFParser implements Parser, RenderingParser {
 
     private final PDFParserConfig defaultConfig = new PDFParserConfig();
 
@@ -276,8 +276,8 @@ the allowlist constrains.
 }
 ----
 
-That fails with "Unrecognized parse-context entry 'java.lang.Runtime'" — the 
class
-is not registered.
+That fails with "Unrecognized parse-context entry 'java.lang.Runtime'. Check 
for a typo; it does
+not match any registered component."
 
 === Untrusted (Wire) Input: Restricted Mode
 
diff --git a/docs/modules/ROOT/pages/maintainers/release-guides/tika.adoc 
b/docs/modules/ROOT/pages/maintainers/release-guides/tika.adoc
index 6777c315f4..1f5be0b337 100644
--- a/docs/modules/ROOT/pages/maintainers/release-guides/tika.adoc
+++ b/docs/modules/ROOT/pages/maintainers/release-guides/tika.adoc
@@ -37,16 +37,16 @@ Before starting the release, run vulnerability and 
dependency audits:
 [source,bash]
 ----
 # Identify vulnerable dependencies (add -Possindex-fail to fail the build on 
findings)
-mvn ossindex:audit
+./mvnw ossindex:audit
 
 # Check for outdated plugins
-mvn versions:display-plugin-updates
+./mvnw versions:display-plugin-updates
 
 # Check for outdated dependencies
-mvn versions:display-dependency-updates
+./mvnw versions:display-dependency-updates
 
 # Run full regression tests
-mvn -Papache-release clean verify
+./mvnw -Papache-release clean verify
 ----
 
 == Release Process
@@ -83,7 +83,7 @@ Run the Apache RAT plugin to verify all files have proper 
license headers:
 
 [source,bash]
 ----
-mvn apache-rat:check
+./mvnw apache-rat:check
 ----
 
 === Step 5: Commit Changes
@@ -112,7 +112,7 @@ Execute the Maven release prepare goal:
 
 [source,bash]
 ----
-mvn release:prepare
+./mvnw release:prepare
 ----
 
 This will prompt you to confirm:
@@ -141,7 +141,7 @@ Execute the Maven release perform goal:
 
 [source,bash]
 ----
-mvn release:perform -Darguments="-DskipITs"
+./mvnw release:perform -Darguments="-DskipITs"
 ----
 
 `-DskipITs` skips integration tests during the inner build.  Tests already
@@ -315,7 +315,7 @@ module that failed rather than starting over:
 [source,bash]
 ----
 cd target/checkout
-mvn deploy -Papache-release -rf :<failed-module> -DskipITs
+./mvnw deploy -Papache-release -rf :<failed-module> -DskipITs
 ----
 
 If the failure was after all modules deployed and only the root-pom dist 
staging
@@ -324,7 +324,7 @@ needs re-running:
 [source,bash]
 ----
 cd target/checkout
-mvn deploy --non-recursive -Papache-release -Dmaven.deploy.skip=true
+./mvnw deploy --non-recursive -Papache-release -Dmaven.deploy.skip=true
 ----
 
 `--non-recursive` runs only the root pom, so the antrun fires with the right
diff --git a/docs/modules/ROOT/pages/migration-to-4x/index.adoc 
b/docs/modules/ROOT/pages/migration-to-4x/index.adoc
index 692dce595e..d7f5959963 100644
--- a/docs/modules/ROOT/pages/migration-to-4x/index.adoc
+++ b/docs/modules/ROOT/pages/migration-to-4x/index.adoc
@@ -25,8 +25,8 @@ Guides and background for upgrading from Apache Tika 3.x.
   SPI signatures, JSON configuration, and the API changes every upgrader hits
 * xref:migration-to-4x/migrating-tika-server-4x.adoc[Tika Server Migration] -- 
endpoint,
   wire-format, and configuration changes in tika-server 4.x
-* xref:migration-to-4x/metadata-changes-4x.adoc[Metadata Changes] -- the full 
3.x -> 4.x
-  key rename tables and the reserved-key write guard
+* xref:migration-to-4x/metadata-changes-4x.adoc[Metadata Changes] -- the 3.x 
-> 4.x key rename
+  tables, summarised by prefix, and the reserved-key write guard
 
 == Background Documentation
 
diff --git a/docs/modules/ROOT/pages/migration-to-4x/metadata-changes-4x.adoc 
b/docs/modules/ROOT/pages/migration-to-4x/metadata-changes-4x.adoc
index 70e5bb0b2d..3edda9fc10 100644
--- a/docs/modules/ROOT/pages/migration-to-4x/metadata-changes-4x.adoc
+++ b/docs/modules/ROOT/pages/migration-to-4x/metadata-changes-4x.adoc
@@ -171,7 +171,9 @@ independent of casing (the name's origin).
   (`xmp*:`), EXIF/`tiff:`, `iptc:`, `photoshop:`, `geo:`, the CF/CMIP 
attributes under `cf:`,
   MAPI property names, email headers, the ECMA-376 OOXML core/extended 
property names
   (`AppVersion`, `lastModifiedBy`, `TotalTime`, …), and the PDF/A/X/VT/UA 
sub-namespaces
-  (`pdfaid:`, `pdfx:`, …) and PDF Info-dict names (`pdf:trapped`, 
`pdf:docinfo:producer`, …).
+  (`pdfaid:`, `pdfx:`, …). PDF Info-dict names (`pdf:docinfo:producer`, 
`pdf:docinfo:trapped`,
+  …) are lowercased rather than verbatim — the dictionary spells them 
`/Producer` and `/Trapped`
+  — but they are unchanged from 3.x.
 
 (The `access_permission:` prefix is also normalized to `access-permission:`. 
The
 `extended-properties:HiddedSlides` entry additionally corrects a long-standing 
spelling typo.)
diff --git a/docs/modules/ROOT/pages/migration-to-4x/migrating-to-4x.adoc 
b/docs/modules/ROOT/pages/migration-to-4x/migrating-to-4x.adoc
index 3c0cb71dde..503f2dcaf5 100644
--- a/docs/modules/ROOT/pages/migration-to-4x/migrating-to-4x.adoc
+++ b/docs/modules/ROOT/pages/migration-to-4x/migrating-to-4x.adoc
@@ -69,9 +69,12 @@ xref:advanced/spooling.adoc[spooling] for the stream 
contract.
 `TikaInputStream` itself dropped several members in 4.0: `isTikaInputStream`, 
`cast`,
 `getPath(int)`, `get(InputStreamFactory)` (both overloads), 
`hasInputStreamFactory`,
 `getInputStreamFactory`, and `setOpenContainer(Object, long)` — along with the
-`InputStreamFactory` class. `get(byte[])` and `getFromContainer` no longer 
declare
-`IOException`. `enableRewind()` now throws a checked `IOException` when bytes 
have
-already been read.
+`InputStreamFactory` class.
+
+NOTE: Two further `TikaInputStream` changes are easy to mistake for 3.x deltas 
but are deltas
+against 4.0.0-beta-1: `get(byte[])` and `getFromContainer` no longer declaring 
`IOException`
+(neither declared it in 3.3.2), and `enableRewind()` throwing a checked 
`IOException` (the method
+did not exist in 3.3.2). Upgrading from 3.x, neither is a change you need to 
make.
 
 [#thin-launcher-zip]
 == `tika-app` and `tika-server` distributions: jar -> zip
diff --git a/docs/modules/ROOT/pages/pipes/plugins/elasticsearch.adoc 
b/docs/modules/ROOT/pages/pipes/plugins/elasticsearch.adoc
index 5cc504dd6d..ffd0757e71 100644
--- a/docs/modules/ROOT/pages/pipes/plugins/elasticsearch.adoc
+++ b/docs/modules/ROOT/pages/pipes/plugins/elasticsearch.adoc
@@ -122,8 +122,8 @@ include::example$pipes-elasticsearch-emitter.json[]
 |Validated non-blank, but not otherwise read: the `_id` is the emit key 
(attachments get the emit key plus a random suffix).
 
 |`attachmentStrategy`
-|`SEPARATE_DOCUMENTS`
-|How attached/embedded documents are indexed. `SEPARATE_DOCUMENTS` — each 
attachment becomes its own top-level document; `PARENT_CHILD` — attachments are 
nested under the parent in a parent/child relation. Absent behaves as 
`SEPARATE_DOCUMENTS`.
+|_none_
+|How attached/embedded documents are indexed. `SEPARATE_DOCUMENTS` — each 
attachment becomes its own top-level document; `PARENT_CHILD` — attachments are 
nested under the parent in a parent/child relation. There is no default: leave 
it unset and embedded documents get neither the `parent` field nor the 
parent/child relation, so set it explicitly.
 
 |`updateStrategy`
 |`UPSERT`
diff --git a/docs/modules/ROOT/pages/pipes/plugins/jdbc.adoc 
b/docs/modules/ROOT/pages/pipes/plugins/jdbc.adoc
index 1ae55988ac..eeb616fe18 100644
--- a/docs/modules/ROOT/pages/pipes/plugins/jdbc.adoc
+++ b/docs/modules/ROOT/pages/pipes/plugins/jdbc.adoc
@@ -158,7 +158,7 @@ In addition to the required `fetcherId` / `emitterId` (see 
xref:pipes/iterators.
 
 |`queryTimeoutSeconds`
 |`-1`
-|Passed straight to `Statement.setQueryTimeout(int seconds)` with no guard. 
Use `0` for the JDBC contract's "no limit" — the `-1` default is outside that 
contract and drivers may reject it.
+|Applied via `Statement.setQueryTimeout(int seconds)` only when greater than 
`0`. `0` and any negative value both leave the driver's own setting alone, so 
the JDBC contract's explicit "no limit" cannot be requested here.
 |===
 
 [#jdbc-reporter]
diff --git a/docs/modules/ROOT/pages/pipes/plugins/kafka.adoc 
b/docs/modules/ROOT/pages/pipes/plugins/kafka.adoc
index e3b448e321..34d695a716 100644
--- a/docs/modules/ROOT/pages/pipes/plugins/kafka.adoc
+++ b/docs/modules/ROOT/pages/pipes/plugins/kafka.adoc
@@ -88,8 +88,8 @@ applies. The Default column below is therefore the Kafka 
client's default.
 |One of `none`, `gzip`, `snappy`, `lz4`, `zstd`.
 
 |`connectionsMaxIdleMs`
-|_ignored_
-|Accepted by the config parser but never passed to the producer, so it has no 
effect. Kafka's own `connections.max.idle.ms` default of `540000` always 
applies.
+|`540000`
+|Passed through to the producer as `connections.max.idle.ms`.
 
 |`deliveryTimeoutMs`
 |`120000`
diff --git a/docs/modules/ROOT/pages/pipes/plugins/opensearch.adoc 
b/docs/modules/ROOT/pages/pipes/plugins/opensearch.adoc
index f6c6f43389..6eb07fc6fb 100644
--- a/docs/modules/ROOT/pages/pipes/plugins/opensearch.adoc
+++ b/docs/modules/ROOT/pages/pipes/plugins/opensearch.adoc
@@ -120,8 +120,8 @@ include::example$pipes-opensearch-emitter.json[]
 |Validated non-blank, but not otherwise read: the `_id` is the emit key 
(attachments get the emit key plus a random suffix).
 
 |`attachmentStrategy`
-|`SEPARATE_DOCUMENTS`
-|How attached/embedded documents are indexed. `SEPARATE_DOCUMENTS` — each 
attachment becomes its own top-level document; `PARENT_CHILD` — attachments are 
nested under the parent in a parent/child relation. Absent behaves as 
`SEPARATE_DOCUMENTS`.
+|_none_
+|How attached/embedded documents are indexed. `SEPARATE_DOCUMENTS` — each 
attachment becomes its own top-level document; `PARENT_CHILD` — attachments are 
nested under the parent in a parent/child relation. There is no default: leave 
it unset and embedded documents get neither the `parent` field nor the 
parent/child relation, so set it explicitly.
 
 |`updateStrategy`
 |`UPSERT`
diff --git a/docs/modules/ROOT/pages/pipes/plugins/solr.adoc 
b/docs/modules/ROOT/pages/pipes/plugins/solr.adoc
index 26940646ca..612089e710 100644
--- a/docs/modules/ROOT/pages/pipes/plugins/solr.adoc
+++ b/docs/modules/ROOT/pages/pipes/plugins/solr.adoc
@@ -124,7 +124,9 @@ include::example$pipes-solr-emitter-zk.json[]
 
 |`authScheme`
 |`basic`
-|Credential scheme. `basic` or `ntlm`.
+|Credential scheme. Only `basic` is supported, and only when `userName` is 
set: the emitter then
+fails to build on any other value. With no `userName`, auth is skipped and 
this setting is ignored
+rather than rejected.
 
 |`proxyHost` / `proxyPort`
 |_none_ / `0`
@@ -179,7 +181,7 @@ In addition to the required `fetcherId` / `emitterId` (see 
xref:pipes/iterators.
 
 |`additionalFields`
 |_empty_
-|Further Solr fields to request alongside the four above.
+|Further Solr fields to request alongside those above. The field list always 
includes `id` as well, whether or not `idField` is set to it.
 
 |`rows`
 |`5000`
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 03f28cf4f4..8729cb116d 100644
--- a/docs/modules/ROOT/pages/pipes/plugins/writing-a-plugin.adoc
+++ b/docs/modules/ROOT/pages/pipes/plugins/writing-a-plugin.adoc
@@ -361,10 +361,12 @@ id, because a pipeline has one iterator and reporters are 
not referenced by id:
 
 Whatever object sits innermost is re-serialized to a string and handed to your 
factory as
 `ExtensionConfig.json()`. Configs are validated when the config loads — an 
unknown component name
-fails immediately, listing the names that *are* available — but instances are 
built lazily, on
-first use.
+fails immediately, listing the names that *are* available. Fetchers and 
emitters are then built
+lazily, on first use; `pipes-iterator` and `pipes-reporters` instances are 
built during config
+load.
 
-An array in any of these sections is rejected outright rather than silently 
ignored.
+An array is rejected outright in `fetchers`, `emitters` and `pipes-iterator`. 
`pipes-reporters` is
+the exception: an array there loads zero reporters and reports no error, so 
keep it an object.
 
 == Developing without repackaging
 
diff --git a/docs/modules/ROOT/pages/pipes/unpack-config.adoc 
b/docs/modules/ROOT/pages/pipes/unpack-config.adoc
index 1ea7cce174..4884b2689e 100644
--- a/docs/modules/ROOT/pages/pipes/unpack-config.adoc
+++ b/docs/modules/ROOT/pages/pipes/unpack-config.adoc
@@ -203,7 +203,7 @@ Produces names like `document-embed-00000001.pdf`. Under 
the `DEFAULT` strategy
 
 == Safety Limits
 
-`maxUnpackBytes` bounds zip bombs and other files that expand to enormous 
sizes. The 10 GB
+`maxUnpackBytes` bounds zip bombs and other files that expand to enormous 
sizes. The 10 GiB
 default suits most corpora; lower it for untrusted input.
 
 Hitting the limit is silent apart from a log line. The embedded file being 
written is
diff --git a/docs/modules/ROOT/pages/using-tika/docker.adoc 
b/docs/modules/ROOT/pages/using-tika/docker.adoc
index ba01436baa..bb991144a1 100644
--- a/docs/modules/ROOT/pages/using-tika/docker.adoc
+++ b/docs/modules/ROOT/pages/using-tika/docker.adoc
@@ -127,7 +127,9 @@ the Tika process. Outside Docker the equivalent is the 
`tika.extras.dir` system
 `/tika`, `/rmeta`, `/meta` and `/unpack` work out of the box. The pipes 
endpoints (`/pipes`,
 `/async`) need the fetcher and emitter plugins for whatever they talk to. The 
image ships
 `tika-pipes-file-system` under `/opt/tika-server/plugins/`; mount any other 
plugin into that
-directory, one subdirectory per plugin.
+directory, one subdirectory per plugin. Plugins publish as `.zip`, so unzip 
yours first and mount
+the resulting directory — the container cannot expand the zip in place, because
+`/opt/tika-server` is copied in root-owned while the server runs as UID 35002.
 
 [source,bash]
 ----
diff --git a/tika-ml/tika-ml-junkdetect-tools/pom.xml 
b/tika-ml/tika-ml-junkdetect-tools/pom.xml
index fe684093cd..fe720dafe8 100644
--- a/tika-ml/tika-ml-junkdetect-tools/pom.xml
+++ b/tika-ml/tika-ml-junkdetect-tools/pom.xml
@@ -100,8 +100,9 @@
         Usage (run from the repo root so the model resource path resolves):
           ./mvnw package -pl tika-ml/tika-ml-junkdetect-tools -am -Ptrain 
-DskipTests \
               -Dmaven.repo.local=.local_m2_repo
-          java -jar 
tika-ml/tika-ml-junkdetect-tools/target/tika-ml-junkdetect-tools-*-tools.jar \
-              [BuildJunkTrainingData|TrainJunkModel|EvalJunkDetector] [args...]
+          java -jar 
tika-ml/tika-ml-junkdetect-tools/target/tika-ml-junkdetect-tools-*-tools.jar 
[args...]
+        The shaded main class is TrainJunkModel; run any other tool with
+          java -cp <that jar> 
org.apache.tika.ml.junkdetect.tools.BuildJunkTrainingData [args...]
       -->
       <id>train</id>
       <build>
diff --git 
a/tika-ml/tika-ml-junkdetect/src/main/java/org/apache/tika/ml/junkdetect/JunkFilterEncodingDetector.java
 
b/tika-ml/tika-ml-junkdetect/src/main/java/org/apache/tika/ml/junkdetect/JunkFilterEncodingDetector.java
index 0253502c32..2a3c08b9fe 100644
--- 
a/tika-ml/tika-ml-junkdetect/src/main/java/org/apache/tika/ml/junkdetect/JunkFilterEncodingDetector.java
+++ 
b/tika-ml/tika-ml-junkdetect/src/main/java/org/apache/tika/ml/junkdetect/JunkFilterEncodingDetector.java
@@ -257,12 +257,11 @@ public class JunkFilterEncodingDetector implements 
MetaEncodingDetector {
         // by shared content (whitespace/digits identical across decodes); on a
         // COMMON-dominated doc the discriminating bytes are diluted and the 
top
         // candidates differ only by noise.  The quality signal is STATISTICAL-
-        // grade evidence, so it may override a higher-evidence anchor
-        // (DECLARATIVE author intent, or STRUCTURAL byte-grammar proof) only 
when
-        // it beats that anchor's score by OVERRIDE_MARGIN; otherwise we defer 
to
-        // the anchor.  This is honest low-confidence behaviour, not a 
tie-break:
-        // where the model has real signal (e.g. UTF-8 over garbage UTF-16, 
Δ≫1)
-        // it still overrides freely.
+        // grade evidence, so it yields to a higher-evidence anchor 
(DECLARATIVE
+        // author intent, or STRUCTURAL byte-grammar proof) whenever the
+        // statistical layer itself abstained -- see the deferral below.  This 
is
+        // honest low-confidence behaviour, not a tie-break: where the model 
has
+        // real signal (e.g. UTF-8 over garbage UTF-16) it still overrides 
freely.
         Charset champion = null;
         double championZ = Double.NEGATIVE_INFINITY;
         Map<Charset, Double> scoreByCharset = new LinkedHashMap<>();
diff --git 
a/tika-parsers/tika-parsers-ml/tika-parser-tess4j-module/src/main/java/org/apache/tika/parser/ocr/tess4j/Tess4JConfig.java
 
b/tika-parsers/tika-parsers-ml/tika-parser-tess4j-module/src/main/java/org/apache/tika/parser/ocr/tess4j/Tess4JConfig.java
index 109a4e5ebb..b8517355a9 100644
--- 
a/tika-parsers/tika-parsers-ml/tika-parser-tess4j-module/src/main/java/org/apache/tika/parser/ocr/tess4j/Tess4JConfig.java
+++ 
b/tika-parsers/tika-parsers-ml/tika-parser-tess4j-module/src/main/java/org/apache/tika/parser/ocr/tess4j/Tess4JConfig.java
@@ -307,11 +307,12 @@ public class Tess4JConfig implements Serializable {
      * pool settings during parse-time configuration.
      * <p>
      * <b>Always blocked:</b> {@code dataPath}, {@code nativeLibPath},
-     * {@code poolSize}.
+     * {@code poolSize}, {@code maxImagePixels}.
      * <p>
      * Paths are blocked to prevent file-system access attacks.
-     * Pool size is blocked because the pool is built at init time and
-     * cannot be resized at runtime.
+     * Pool size is blocked because the pool is built at init time and cannot
+     * be resized.  {@code maxImagePixels} is read per parse, but it is the
+     * OOM guard on image decode, so a caller must not be able to raise it.
      */
     public static class RuntimeConfig extends Tess4JConfig {
 
diff --git 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-ocr-module/src/main/java/org/apache/tika/parser/ocr/ImagePreprocessor.java
 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-ocr-module/src/main/java/org/apache/tika/parser/ocr/ImagePreprocessor.java
index 07ffff21c6..fdb4c42eff 100644
--- 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-ocr-module/src/main/java/org/apache/tika/parser/ocr/ImagePreprocessor.java
+++ 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-ocr-module/src/main/java/org/apache/tika/parser/ocr/ImagePreprocessor.java
@@ -55,7 +55,7 @@ class ImagePreprocessor implements Serializable {
         double angle = config.isApplyRotation() ? getAngle(sourceFile, 
metadata) : 0d;
 
         if (config.isEnableImagePreprocessing() || (config.isApplyRotation() 
&& angle != 0)) {
-            // process the image - parameter values can be set in 
TesseractOCRConfig.properties
+            // process the image - parameter values come from 
TesseractOCRConfig
             //
             // On Windows TesseractOCRParser.getImageMagickProg() returns 
"magick", i.e. the
             // ImageMagick 7 program. IM7's native command form is
diff --git 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-ocr-module/src/main/java/org/apache/tika/parser/ocr/TesseractOCRConfig.java
 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-ocr-module/src/main/java/org/apache/tika/parser/ocr/TesseractOCRConfig.java
index 93366eedbc..62b209cfe1 100644
--- 
a/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-ocr-module/src/main/java/org/apache/tika/parser/ocr/TesseractOCRConfig.java
+++ 
b/tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-ocr-module/src/main/java/org/apache/tika/parser/ocr/TesseractOCRConfig.java
@@ -511,10 +511,6 @@ public class TesseractOCRConfig implements Serializable {
     /**
      * Add a key-value pair to pass to Tesseract using its -c command line 
option.
      * To see the possible options, run tesseract --print-parameters.
-     * <p>
-     * You may also add these parameters in TesseractOCRConfig.properties; any
-     * key-value pair in the properties file where the key contains an 
underscore
-     * is passed directly to Tesseract.
      *
      * @param key
      * @param value
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-atlassian-jwt/src/main/java/org/apache/tika/pipes/fetcher/atlassianjwt/AtlassianJwtFetcherFactory.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-atlassian-jwt/src/main/java/org/apache/tika/pipes/fetcher/atlassianjwt/AtlassianJwtFetcherFactory.java
index 145bc80bee..c30942b22f 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-atlassian-jwt/src/main/java/org/apache/tika/pipes/fetcher/atlassianjwt/AtlassianJwtFetcherFactory.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-atlassian-jwt/src/main/java/org/apache/tika/pipes/fetcher/atlassianjwt/AtlassianJwtFetcherFactory.java
@@ -32,8 +32,8 @@ import org.apache.tika.plugins.ExtensionConfig;
  * <p>Example JSON configuration:
  * <pre>
  * "fetchers": {
- *   "atlassian-jwt-fetcher": {
- *     "my-atlassian-fetcher": {
+ *   "my-atlassian-fetcher": {
+ *     "atlassian-jwt-fetcher": {
  *       "sharedSecret": "your-shared-secret",
  *       "issuer": "your-app-key",
  *       "connectTimeoutMillis": 30000,
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/emitter/azblob/AZBlobEmitter.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/emitter/azblob/AZBlobEmitter.java
index 41f6baa7df..bbbe17cb5e 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/emitter/azblob/AZBlobEmitter.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/emitter/azblob/AZBlobEmitter.java
@@ -53,8 +53,8 @@ import org.apache.tika.utils.StringUtils;
  * <pre>
  * {
  *   "emitters": {
- *     "az-blob-emitter": {
- *       "my-azure": {
+ *     "my-azure": {
+ *       "az-blob-emitter": {
  *         "endpoint": "https://myaccount.blob.core.windows.net";,
  *         "sasToken": "sv=2020-08-04&amp;ss=b...",
  *         "container": "my-container",
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/emitter/azblob/AZBlobEmitterFactory.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/emitter/azblob/AZBlobEmitterFactory.java
index c24ea22d3d..0729a8df56 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/emitter/azblob/AZBlobEmitterFactory.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/emitter/azblob/AZBlobEmitterFactory.java
@@ -31,8 +31,8 @@ import org.apache.tika.plugins.ExtensionConfig;
  * <p>Example JSON configuration:
  * <pre>
  * "emitters": {
- *   "az-blob-emitter": {
- *     "my-az-emitter": {
+ *   "my-az-emitter": {
+ *     "az-blob-emitter": {
  *       "sasToken": "your-sas-token",
  *       "endpoint": "https://account.blob.core.windows.net";,
  *       "container": "my-container",
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/fetcher/azblob/AZBlobFetcherFactory.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/fetcher/azblob/AZBlobFetcherFactory.java
index 5508e69be5..2667526ca0 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/fetcher/azblob/AZBlobFetcherFactory.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-az-blob/src/main/java/org/apache/tika/pipes/fetcher/azblob/AZBlobFetcherFactory.java
@@ -32,8 +32,8 @@ import org.apache.tika.plugins.ExtensionConfig;
  * <p>Example JSON configuration:
  * <pre>
  * "fetchers": {
- *   "az-blob-fetcher": {
- *     "my-az-fetcher": {
+ *   "my-az-fetcher": {
+ *     "az-blob-fetcher": {
  *       "sasToken": "your-sas-token",
  *       "endpoint": "https://account.blob.core.windows.net";,
  *       "container": "my-container",
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-es/src/main/java/org/apache/tika/pipes/emitter/es/ESEmitterFactory.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-es/src/main/java/org/apache/tika/pipes/emitter/es/ESEmitterFactory.java
index 21771d1d5d..1515b69bdf 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-es/src/main/java/org/apache/tika/pipes/emitter/es/ESEmitterFactory.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-es/src/main/java/org/apache/tika/pipes/emitter/es/ESEmitterFactory.java
@@ -31,8 +31,8 @@ import org.apache.tika.plugins.ExtensionConfig;
  * <p>Example JSON configuration:
  * <pre>
  * "emitters": {
- *   "es-emitter": {
- *     "my-es-emitter": {
+ *   "my-es-emitter": {
+ *     "es-emitter": {
  *       "esUrl": "https://localhost:9200/my-index";,
  *       "idField": "id",
  *       "apiKey": "base64-encoded-id:api_key",
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/emitter/fs/FileSystemEmitterFactory.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/emitter/fs/FileSystemEmitterFactory.java
index 0160616e2e..7a86079594 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/emitter/fs/FileSystemEmitterFactory.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/emitter/fs/FileSystemEmitterFactory.java
@@ -31,8 +31,8 @@ import org.apache.tika.plugins.ExtensionConfig;
  * <p>Example JSON configuration:
  * <pre>
  * "emitters": {
- *   "file-system-emitter": {
- *     "my-emitter": {
+ *   "my-emitter": {
+ *     "file-system-emitter": {
  *       "basePath": "/path/to/output",
  *       "fileExtension": "json",
  *       "onExists": "SKIP",
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/fetcher/fs/FileSystemFetcherFactory.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/fetcher/fs/FileSystemFetcherFactory.java
index 6483f32fe7..fa2b672711 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/fetcher/fs/FileSystemFetcherFactory.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-file-system/src/main/java/org/apache/tika/pipes/fetcher/fs/FileSystemFetcherFactory.java
@@ -31,8 +31,8 @@ import org.apache.tika.plugins.ExtensionConfig;
  * <p>Example JSON configuration:
  * <pre>
  * "fetchers": {
- *   "file-system-fetcher": {
- *     "my-fetcher": {
+ *   "my-fetcher": {
+ *     "file-system-fetcher": {
  *       "basePath": "/path/to/files",
  *       "extractFileSystemMetadata": true
  *     }
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/emitter/gcs/GCSEmitter.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/emitter/gcs/GCSEmitter.java
index 0e70cac0a8..e3a9080e5d 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/emitter/gcs/GCSEmitter.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/emitter/gcs/GCSEmitter.java
@@ -49,8 +49,8 @@ import org.apache.tika.utils.StringUtils;
  * <pre>
  * {
  *   "emitters": {
- *     "gcs-emitter": {
- *       "my-gcs": {
+ *     "my-gcs": {
+ *       "gcs-emitter": {
  *         "projectId": "my-project-id",
  *         "bucket": "my-bucket",
  *         "prefix": "output",
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/emitter/gcs/GCSEmitterFactory.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/emitter/gcs/GCSEmitterFactory.java
index a0c7df0291..f8b088229c 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/emitter/gcs/GCSEmitterFactory.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/emitter/gcs/GCSEmitterFactory.java
@@ -31,8 +31,8 @@ import org.apache.tika.plugins.ExtensionConfig;
  * <p>Example JSON configuration:
  * <pre>
  * "emitters": {
- *   "gcs-emitter": {
- *     "my-gcs-emitter": {
+ *   "my-gcs-emitter": {
+ *     "gcs-emitter": {
  *       "projectId": "my-project",
  *       "bucket": "my-bucket",
  *       "prefix": "output/",
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/fetcher/gcs/GCSFetcherFactory.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/fetcher/gcs/GCSFetcherFactory.java
index fceca509c5..b426cabdef 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/fetcher/gcs/GCSFetcherFactory.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-gcs/src/main/java/org/apache/tika/pipes/fetcher/gcs/GCSFetcherFactory.java
@@ -32,8 +32,8 @@ import org.apache.tika.plugins.ExtensionConfig;
  * <p>Example JSON configuration:
  * <pre>
  * "fetchers": {
- *   "gcs-fetcher": {
- *     "my-gcs-fetcher": {
+ *   "my-gcs-fetcher": {
+ *     "gcs-fetcher": {
  *       "projectId": "my-project",
  *       "bucket": "my-bucket",
  *       "spoolToTemp": true,
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-google-drive/src/main/java/org/apache/tika/pipes/fetcher/googledrive/GoogleDriveFetcherFactory.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-google-drive/src/main/java/org/apache/tika/pipes/fetcher/googledrive/GoogleDriveFetcherFactory.java
index a213484b72..07f186ba2d 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-google-drive/src/main/java/org/apache/tika/pipes/fetcher/googledrive/GoogleDriveFetcherFactory.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-google-drive/src/main/java/org/apache/tika/pipes/fetcher/googledrive/GoogleDriveFetcherFactory.java
@@ -32,8 +32,8 @@ import org.apache.tika.plugins.ExtensionConfig;
  * <p>Example JSON configuration:
  * <pre>
  * "fetchers": {
- *   "google-drive-fetcher": {
- *     "my-drive-fetcher": {
+ *   "my-drive-fetcher": {
+ *     "google-drive-fetcher": {
  *       "serviceAccountCredentialsPath": "/path/to/credentials.json",
  *       "impersonatedUser": "[email protected]"
  *     }
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-http/src/main/java/org/apache/tika/pipes/fetcher/http/HttpFetcherFactory.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-http/src/main/java/org/apache/tika/pipes/fetcher/http/HttpFetcherFactory.java
index d2df6bdfb6..cb9cc593d5 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-http/src/main/java/org/apache/tika/pipes/fetcher/http/HttpFetcherFactory.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-http/src/main/java/org/apache/tika/pipes/fetcher/http/HttpFetcherFactory.java
@@ -32,8 +32,8 @@ import org.apache.tika.plugins.ExtensionConfig;
  * <p>Example JSON configuration:
  * <pre>
  * "fetchers": {
- *   "http-fetcher": {
- *     "my-http-fetcher": {
+ *   "my-http-fetcher": {
+ *     "http-fetcher": {
  *       "userName": "user",
  *       "password": "pass",
  *       "connectTimeoutMillis": 30000,
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/java/org/apache/tika/pipes/emitter/jdbc/JDBCEmitter.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/java/org/apache/tika/pipes/emitter/jdbc/JDBCEmitter.java
index 9f850cf83a..b88db8e1f9 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/java/org/apache/tika/pipes/emitter/jdbc/JDBCEmitter.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/java/org/apache/tika/pipes/emitter/jdbc/JDBCEmitter.java
@@ -58,8 +58,8 @@ import org.apache.tika.utils.StringUtils;
  * <pre>
  * {
  *   "emitters": {
- *     "jdbc-emitter": {
- *       "my-db": {
+ *     "my-db": {
+ *       "jdbc-emitter": {
  *         "connection": "jdbc:postgresql://localhost/mydb",
  *         "createTable": "CREATE TABLE IF NOT EXISTS docs (path 
VARCHAR(1024), content TEXT)",
  *         "insert": "INSERT INTO docs (path, content) VALUES (?, ?)",
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/java/org/apache/tika/pipes/emitter/jdbc/JDBCEmitterFactory.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/java/org/apache/tika/pipes/emitter/jdbc/JDBCEmitterFactory.java
index a63c699512..7155b0a4b3 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/java/org/apache/tika/pipes/emitter/jdbc/JDBCEmitterFactory.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-jdbc/src/main/java/org/apache/tika/pipes/emitter/jdbc/JDBCEmitterFactory.java
@@ -31,8 +31,8 @@ import org.apache.tika.plugins.ExtensionConfig;
  * <p>Example JSON configuration:
  * <pre>
  * "emitters": {
- *   "jdbc-emitter": {
- *     "my-jdbc-emitter": {
+ *   "my-jdbc-emitter": {
+ *     "jdbc-emitter": {
  *       "connection": "jdbc:postgresql://localhost/mydb",
  *       "insert": "insert into docs (id, content) values (?, ?)",
  *       "keys": {"id": "tk:content", "content": "content"}
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-kafka/src/main/java/org/apache/tika/pipes/emitter/kafka/KafkaEmitter.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-kafka/src/main/java/org/apache/tika/pipes/emitter/kafka/KafkaEmitter.java
index 9b25d0748f..b4b95aacb2 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-kafka/src/main/java/org/apache/tika/pipes/emitter/kafka/KafkaEmitter.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-kafka/src/main/java/org/apache/tika/pipes/emitter/kafka/KafkaEmitter.java
@@ -44,8 +44,8 @@ import org.apache.tika.plugins.ExtensionConfig;
  * <pre>
  * {
  *   "emitters": {
- *     "kafka-emitter": {
- *       "my-kafka": {
+ *     "my-kafka": {
+ *       "kafka-emitter": {
  *         "topic": "tika-output",
  *         "bootstrapServers": "localhost:9092",
  *         "acks": "all",
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-kafka/src/main/java/org/apache/tika/pipes/emitter/kafka/KafkaEmitterFactory.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-kafka/src/main/java/org/apache/tika/pipes/emitter/kafka/KafkaEmitterFactory.java
index d69874ded7..1bff542561 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-kafka/src/main/java/org/apache/tika/pipes/emitter/kafka/KafkaEmitterFactory.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-kafka/src/main/java/org/apache/tika/pipes/emitter/kafka/KafkaEmitterFactory.java
@@ -31,8 +31,8 @@ import org.apache.tika.plugins.ExtensionConfig;
  * <p>Example JSON configuration:
  * <pre>
  * "emitters": {
- *   "kafka-emitter": {
- *     "my-kafka-emitter": {
+ *   "my-kafka-emitter": {
+ *     "kafka-emitter": {
  *       "topic": "my-topic",
  *       "bootstrapServers": "localhost:9092",
  *       "acks": "all",
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-microsoft-graph/src/main/java/org/apache/tika/pipes/fetchers/microsoftgraph/MicrosoftGraphFetcherFactory.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-microsoft-graph/src/main/java/org/apache/tika/pipes/fetchers/microsoftgraph/MicrosoftGraphFetcherFactory.java
index a0b4e88c1b..0ea0a18888 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-microsoft-graph/src/main/java/org/apache/tika/pipes/fetchers/microsoftgraph/MicrosoftGraphFetcherFactory.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-microsoft-graph/src/main/java/org/apache/tika/pipes/fetchers/microsoftgraph/MicrosoftGraphFetcherFactory.java
@@ -32,8 +32,8 @@ import org.apache.tika.plugins.ExtensionConfig;
  * <p>Example JSON configuration:
  * <pre>
  * "fetchers": {
- *   "microsoft-graph-fetcher": {
- *     "my-graph-fetcher": {
+ *   "my-graph-fetcher": {
+ *     "microsoft-graph-fetcher": {
  *       "spoolToTemp": true,
  *       "scopes": ["https://graph.microsoft.com/.default";],
  *       "clientSecretCredentialsConfig": {
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-opensearch/src/main/java/org/apache/tika/pipes/emitter/opensearch/OpenSearchEmitterFactory.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-opensearch/src/main/java/org/apache/tika/pipes/emitter/opensearch/OpenSearchEmitterFactory.java
index 7d42c1e310..56fb958bc0 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-opensearch/src/main/java/org/apache/tika/pipes/emitter/opensearch/OpenSearchEmitterFactory.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-opensearch/src/main/java/org/apache/tika/pipes/emitter/opensearch/OpenSearchEmitterFactory.java
@@ -31,8 +31,8 @@ import org.apache.tika.plugins.ExtensionConfig;
  * <p>Example JSON configuration:
  * <pre>
  * "emitters": {
- *   "opensearch-emitter": {
- *     "my-opensearch-emitter": {
+ *   "my-opensearch-emitter": {
+ *     "opensearch-emitter": {
  *       "openSearchUrl": "http://localhost:9200/my-index";,
  *       "idField": "id",
  *       "attachmentStrategy": "PARENT_CHILD",
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/emitter/s3/S3Emitter.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/emitter/s3/S3Emitter.java
index 0462d7b459..c73a14f638 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/emitter/s3/S3Emitter.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/emitter/s3/S3Emitter.java
@@ -68,8 +68,8 @@ import org.apache.tika.utils.StringUtils;
  * <pre>
  * {
  *   "emitters": {
- *     "s3-emitter": {
- *       "my-s3": {
+ *     "my-s3": {
+ *       "s3-emitter": {
  *         "region": "us-east-1",
  *         "bucket": "my-bucket",
  *         "credentialsProvider": "profile",
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/emitter/s3/S3EmitterFactory.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/emitter/s3/S3EmitterFactory.java
index 99d45b7a7b..ecf36a20b3 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/emitter/s3/S3EmitterFactory.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/emitter/s3/S3EmitterFactory.java
@@ -31,8 +31,8 @@ import org.apache.tika.plugins.ExtensionConfig;
  * <p>Example JSON configuration:
  * <pre>
  * "emitters": {
- *   "s3-emitter": {
- *     "my-s3-emitter": {
+ *   "my-s3-emitter": {
+ *     "s3-emitter": {
  *       "region": "us-east-1",
  *       "bucket": "my-bucket",
  *       "credentialsProvider": "profile",
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/fetcher/s3/S3FetcherFactory.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/fetcher/s3/S3FetcherFactory.java
index fd98da1e22..2115a97aeb 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/fetcher/s3/S3FetcherFactory.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-s3/src/main/java/org/apache/tika/pipes/fetcher/s3/S3FetcherFactory.java
@@ -32,8 +32,8 @@ import org.apache.tika.plugins.ExtensionConfig;
  * <p>Example JSON configuration:
  * <pre>
  * "fetchers": {
- *   "s3-fetcher": {
- *     "my-s3-fetcher": {
+ *   "my-s3-fetcher": {
+ *     "s3-fetcher": {
  *       "region": "us-east-1",
  *       "bucket": "my-bucket",
  *       "credentialsProvider": "profile",
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-solr/src/main/java/org/apache/tika/pipes/emitter/solr/SolrEmitter.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-solr/src/main/java/org/apache/tika/pipes/emitter/solr/SolrEmitter.java
index c7a4477282..8ce35dc441 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-solr/src/main/java/org/apache/tika/pipes/emitter/solr/SolrEmitter.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-solr/src/main/java/org/apache/tika/pipes/emitter/solr/SolrEmitter.java
@@ -49,8 +49,8 @@ import org.apache.tika.utils.StringUtils;
  * <pre>
  * {
  *   "emitters": {
- *     "solr-emitter": {
- *       "my-solr": {
+ *     "my-solr": {
+ *       "solr-emitter": {
  *         "solrCollection": "my-collection",
  *         "solrUrls": ["http://localhost:8983/solr";],
  *         "idField": "id",
diff --git 
a/tika-pipes/tika-pipes-plugins/tika-pipes-solr/src/main/java/org/apache/tika/pipes/emitter/solr/SolrEmitterFactory.java
 
b/tika-pipes/tika-pipes-plugins/tika-pipes-solr/src/main/java/org/apache/tika/pipes/emitter/solr/SolrEmitterFactory.java
index ebd8932924..33fe4333dc 100644
--- 
a/tika-pipes/tika-pipes-plugins/tika-pipes-solr/src/main/java/org/apache/tika/pipes/emitter/solr/SolrEmitterFactory.java
+++ 
b/tika-pipes/tika-pipes-plugins/tika-pipes-solr/src/main/java/org/apache/tika/pipes/emitter/solr/SolrEmitterFactory.java
@@ -31,8 +31,8 @@ import org.apache.tika.plugins.ExtensionConfig;
  * <p>Example JSON configuration:
  * <pre>
  * "emitters": {
- *   "solr-emitter": {
- *     "my-solr-emitter": {
+ *   "my-solr-emitter": {
+ *     "solr-emitter": {
  *       "solrCollection": "my-collection",
  *       "solrUrls": ["http://localhost:8983/solr";],
  *       "idField": "id",

Reply via email to