Migrating to Tika 4.x

This guide covers the changes required when upgrading from Apache Tika 3.x to 4.x.

See the Roadmap for version timelines and support schedules.

Requirements

  • Java 17 or later (upgraded from Java 11 in 3.x)

tika-app distribution: jar → zip

In 3.x, tika-app-<version>.jar was a self-contained fat jar — you could drop it anywhere and run java -jar tika-app.jar. In 4.x it is a thin launcher that depends on the parsers, the Tika Pipes processor, and other modules living in an adjacent lib/ directory. Running the bare jar by itself will fail with NoClassDefFoundError.

Download tika-app-<version>.zip and run from inside the unzipped directory so lib/ (and plugins/) sit alongside the jar:

unzip tika-app-<version>.zip
cd tika-app-<version>
java -jar tika-app-<version>.jar [option...] [file...]

If you have build scripts or container images that drop in just the jar, update them to unpack the zip and run from inside it.

Default content handler: XHTML/XML → Markdown

In 3.x the default content handler produced XHTML/XML. In 4.x the default is Markdown everywhere:

  • tika-app outputs Markdown by default (was XHTML). Pass -x/--xml, -h/--html, or -t/--text to choose another format.

  • tika-server — the /tika and /rmeta endpoints return Markdown content by default (was XHTML/XML). Use an explicit handler path (/tika/xml, /rmeta/xml, …​) or the X-Tika-Handler header to choose another format.

  • The async/pipes CLI emits Markdown by default (was plain text). Use --handler x (etc.) to choose another format.

If you parse the extracted content programmatically and expect XHTML/XML, request it explicitly as shown above (TIKA-4663).

Configuration: XML to JSON

Tika 4.x uses JSON configuration files instead of XML. The legacy tika-config.xml format is no longer supported.

Automatic Conversion

Tika provides a conversion tool in tika-app to help migrate your XML configuration:

java -jar tika-app.jar --convert-config-xml-to-json=tika-config.xml > tika-config.json

The converted JSON is written to standard output, so redirect it to the file of your choice (as shown above). No separate --config argument is needed.

The converter currently supports:

  • Parsers section - parser declarations with parameters and exclusions

  • Parameter types - bool, int, long, double, float, string, list, and map

  • Special handling - TesseractOCR’s otherTesseractSettings list is automatically converted to the otherTesseractConfig map format

The converter is a starting point, not a complete translation. It handles only the parsers section, and some 3.x options were genuinely removed or restructured in 4.x with no mechanical equivalent. Review the generated JSON and confirm it loads before relying on it.

Example Conversion

XML Format (3.x):

<properties>
  <parsers>
    <parser class="org.apache.tika.parser.pdf.PDFParser">
      <params>
        <param name="sortByPosition" type="bool">true</param>
        <param name="maxMainMemoryBytes" type="long">1000000</param>
      </params>
    </parser>
    <parser class="org.apache.tika.parser.DefaultParser">
      <parser-exclude class="org.apache.tika.parser.pdf.PDFParser"/>
    </parser>
  </parsers>
</properties>

JSON Format (4.x):

{
  "parsers": [
    {
      "pdf-parser": {
        "sortByPosition": true,
        "maxMainMemoryBytes": 1000000
      }
    },
    {
      "default-parser": {}
    }
  ]
}
A parsers list loads only the parsers it names. The default-parser entry above restores all the other parsers (it is the JSON equivalent of the 3.x DefaultParser). Configuring a parser automatically excludes its default copy, so there is no duplication; explicit exclude directives are only needed to disable a parser without replacing it.

Key Differences

Aspect XML (3.x) JSON (4.x)

Class references

Full class name (org.apache.tika.parser.pdf.PDFParser)

Kebab-case component name (pdf-parser)

Parameters

<param name="…​" type="…​">value</param>

Direct key-value pairs

Exclusions

<parser-exclude class="…​"/>

"exclude": ["component-name"] (only needed to disable a parser entirely)

Limitations

The automatic converter has some limitations:

  • Only the parsers section is currently converted

  • Detectors and other sections require manual migration

  • Custom or third-party parsers not in the registry will use kebab-case name conversion

Parser Configuration Changes

The configuration options for PDFParser and TesseractOCRParser have changed significantly in 4.x. The automatic converter will migrate your parameter names, but you should review the updated documentation to ensure your configuration is optimal.

See the Configuration section for full details, including:

For the general serialization model and how JSON configuration works, see Serialization and Configuration.

Full Configuration Example

Below is a complete example of a Tika 4.x JSON configuration file with commonly configured parsers:

{
  "parsers": [
    {
      "pdf-parser": {
        "extractInlineImages": true,
        "extractUniqueInlineImagesOnly": true,
        "sortByPosition": true,
        "maxMainMemoryBytes": 1000000000
      }
    },
    {
      "tesseract-ocr-parser": {
        "language": "eng+fra",
        "pageSegMode": "1",
        "timeoutSeconds": 300,
        "otherTesseractConfig": {
          "textord_initialx_ile": "0.75",
          "textord_noise_hfract": "0.15625"
        }
      }
    },
    {
      "default-parser": {}
    }
  ]
}
This example shows common options. See the individual parser configuration pages for complete documentation of all available options.

Metadata Key Changes

Tika 4.x prefixes all "user generated" metadata keys to prevent overwrites and improve namespace clarity.

See Metadata Changes in 4.x for complete details, including a full table of changes and code migration examples.

API Changes

TikaConfig replaced by TikaLoader

TikaConfig has been removed. Use TikaLoader from tika-serialization instead.

3.x:

TikaConfig config = new TikaConfig(getClass().getClassLoader());
Parser parser = config.getParser();
Detector detector = config.getDetector();
AutoDetectParser autoDetect = new AutoDetectParser(config);

4.x:

// Default configuration (SPI-discovered components)
TikaLoader loader = TikaLoader.loadDefault(getClass().getClassLoader());

// Or from a JSON config file
TikaLoader loader = TikaLoader.load(Path.of("tika-config.json"));

// Access components
Parser parser = loader.loadParsers();
Detector detector = loader.loadDetectors();
Parser autoDetect = loader.loadAutoDetectParser();
ParseContext context = loader.loadParseContext();
TikaLoader is in the tika-serialization module. Add tika-serialization as a dependency if you were previously only depending on tika-core. See Serialization and Configuration for the full TikaLoader API.

For simple use cases, the Tika facade and DefaultParser still work without TikaLoader:

// Simple facade (unchanged from 3.x)
Tika tika = new Tika();
String text = tika.parseToString(file);

// Direct parser use (unchanged from 3.x)
Parser parser = new DefaultParser();

ExternalParser

The legacy ExternalParser and CompositeExternalParser have been removed. External parsers must now be explicitly configured via JSON. See External Parser Configuration for details.

Deprecations and Removals

  • TikaConfig — replaced by TikaLoader

  • CompositeExternalParser — external parsers now require explicit JSON configuration

  • ExternalParsersFactory and XML-based external parser auto-discovery

  • DOM-based OOXML extractors (XWPFWordExtractorDecorator, XSLFPowerPointExtractorDecorator) — SAX-based extractors are now the only implementation