Serialization in Tika 4.x
The JSON serialization design behind Tika 4.x configuration. For the API you actually call, see Serialization and Configuration; for the wider 4.x architecture, see Design Notes for 4.x.
Design Goals
- Jackson, minimally wrapped
-
Use Jackson as much as possible, with as few custom serializers and annotations as possible. Jackson dependencies stay out of the core modules so those modules remain free of it.
- Friendly names, not class names
-
Configuration refers to components by friendly names such as
pdf-parser. The name belongs to the configured item, not to a configuration class. - Custom classes via
@TikaComponent, not polymorphic typing -
Annotate a class with
@TikaComponentand the annotation processor generates aMETA-INF/tika/*.idxregistry entry at compile time. Any class whose.idxentry is on the classpath can then be named in JSON. Unregistered classes and packages cannot be instantiated — there is no package-pattern allowlist and noClass.forNamefallback. - The same shape at init and at runtime
-
Initialization and runtime configuration should look identical and share the same underlying code. Security constraints may still restrict which fields are modifiable at runtime.
- Config objects, not field annotations
-
Configuration lives in config objects rather than annotated parser fields, so parsers stay usable from multiple threads; a parser reads its settings from
ParseContextat parse time. - One config format across systems
-
The same configuration passes from a user’s client, through the tika-server REST API, into the tika-pipes infrastructure, without translation at each hop.
Discovering the friendly name for a component
The 4.x JSON config refers to parsers, detectors, fetchers, emitters, and other components
by their friendly name (e.g., pdf-parser, file-system-fetcher). To map a Java class
to its friendly name (or vice versa), use any of:
-
tika-app --list-parser-names/--list-detector-names— emits each registered class with its friendly name as tab-separatedclass<TAB>friendly-name:java -jar tika-app.jar --list-parser-names # org.apache.tika.parser.pdf.PDFParser pdf-parser # org.apache.tika.parser.html.JSoupParser jsoup-parser # ...The mapping comes from the
META-INF/tika/parsers.idx/detectors.idxfiles generated at compile time by the@TikaComponentannotation processor. The underlying lookup iso.a.t.config.loader.ComponentRegistry.getFriendlyName(Class). -
Per-parser configuration pages under Configuration show the friendly name in their page title and JSON examples.
-
The naming convention — when
@TikaComponenthas no explicitname, the friendly name is derived from the class’s simple name via the kebab-case rule ino.a.t.config.loader.KebabCaseConverter. Examples:Class Friendly name PDFParserpdf-parserTesseractOCRParsertesseract-ocr-parserAutoDetectParserauto-detect-parserFileSystemFetcherfile-system-fetcherSolrEmittersolr-emitter
The --list-parsers, --list-detectors, and --list-parser-details commands
print the hierarchical, human-oriented view (class names with composite parsers
indented). Use the --list-*-names variants when you want a machine-readable mapping.
|
Initialization Structure
Tier 1 — the top-level config sections, each loaded into a component of a known kind:
- ID objects
-
Fetchers and emitters — components addressed by a unique identifier.
- Composite objects
-
Parsers and detectors — components that aggregate other components.
- Single objects
-
The
pipes,grpc, andserverconfigurations.
Tier 2 — anything else that carries @TikaComponent, bound by friendly name inside the
parse-context section.
Runtime Patterns
- Backwards compatibility
-
New capabilities are added to
ParseContext, keyed by their interface, so an existing context keeps working. - Partial configuration updates
-
A partial JSON object may specify only the updates to the initialization configuration; a complete configuration document is not required.
- Self-configuring components in pipes
-
In the pipes infrastructure, components configure themselves rather than being configured by a central loader, so nothing has to load classes like
PDFParserto configure them.
Security Model
Configuration files read at initialization are treated as trusted sources. Component
instantiation from JSON is restricted to classes registered at compile time by the
@TikaComponent annotation processor (META-INF/tika/*.idx files); unknown class names are
rejected, and there is no Jackson default typing.
Untrusted per-request configuration (tika-server requests, pipes FetchEmitTuple`s) is
deserialized in a restricted mode that additionally applies a fail-closed allowlist of
context-key types: only metadata/output-shaping components (e.g. `MetadataFilter,
ContentHandlerFactory, DigesterFactory) may be bound from the wire; Parser, Detector,
Renderer, and similar are blocked before anything is constructed.
Note the boundary: the allowlist blocks binding a component from the wire, not configuring
one that is already loaded. Self-configuring components — every Parser among them — have
their config subtree passed through unscanned, so a per-request config can still set parser
options (including ones that spawn external processes, such as OCR). This is why
allowPerRequestConfig is a separate gate and is off by default; the allowlist alone does
not make per-request configuration safe to expose.