Tess4J OCR Parser
|
Advanced users only. If that doesn’t describe you, don’t reach for this parser — and that’s perfectly fine.
|
Tess4JParser calls the Tesseract native library in-process via
Tess4J and JNA instead of spawning a tesseract child process
per image. That removes the per-file process-spawn overhead and can be significantly faster on
large batches.
The native Tesseract handle is not thread-safe, so the parser keeps a configurable pool of
Tesseract instances that threads borrow and return; the parser itself is safe for concurrent use.
| Run this parser in a forked JVM using tika-pipes, ideally inside a Docker container. A segfault or memory leak in the native Tesseract or Leptonica code takes down whatever JVM loaded it. Do not put it in a long-lived application server process. |
Module dependency
The parser lives in the tika-parser-tess4j-module artifact:
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-parser-tess4j-module</artifactId>
<version>4.1.0-SNAPSHOT</version>
</dependency>
Prerequisites
You must have the Tesseract and Leptonica shared libraries installed on the machine where the parser runs. The tess4j jar bundles Windows DLLs only — on macOS and Linux you are responsible for installing the native libraries yourself.
-
Debian / Ubuntu:
apt-get install libtesseract-dev libleptonica-dev tesseract-ocr-eng -
RHEL / Fedora:
dnf install tesseract-devel leptonica-devel tesseract-langpack-eng -
macOS (Homebrew):
brew install tesseract
You also need the tessdata language files. The dataPath configuration
option must point to the directory containing them (e.g.,
/usr/share/tesseract-ocr/5/tessdata).
Native library path (jna.library.path)
|
JNA must be able to find You have several options:
You are on your own here. The correct path depends entirely on your OS, distribution, and how you installed Tesseract. Common values:
|
Basic Configuration
{
"parsers": [
{
"tess4j-parser": {
"dataPath": "/usr/share/tesseract-ocr/5/tessdata",
"nativeLibPath": "/usr/lib/x86_64-linux-gnu",
"poolSize": 4
}
}
]
}
Full Configuration
{
"parsers": [
{
"tess4j-parser": {
"dataPath": "/usr/share/tesseract-ocr/5/tessdata",
"nativeLibPath": "/usr/lib/x86_64-linux-gnu",
"language": "eng",
"pageSegMode": 1,
"ocrEngineMode": 3,
"poolSize": 4,
"timeoutMillis": 120000,
"dpi": 300,
"minFileSizeToOcr": 0,
"maxFileSizeToOcr": 2147483647,
"maxImagePixels": 100000000,
"skipOcr": false
}
}
]
}
Configuration options reference
| Property | Default | Description |
|---|---|---|
|
|
Path to the tessdata directory containing language data files. Required on macOS and Linux. |
|
|
Path to the directory containing |
|
|
Tesseract language(s). Multiple languages separated by |
|
|
Page segmentation mode (0-13). 1 = automatic with OSD. |
|
|
OCR engine mode. 0 = legacy, 1 = LSTM only, 2 = legacy + LSTM, 3 = default (whatever is available). |
|
|
Number of |
|
|
Timeout (milliseconds) applied both to waiting for a pooled |
|
|
DPI for image rendering. |
|
|
Minimum input file size in bytes. Smaller files are skipped. |
|
|
Maximum input file size in bytes. Larger files are skipped. |
|
|
Maximum decoded-image area. Larger images are skipped. Guards against decompression-bomb inputs that would blow up memory before OCR even starts. |
|
|
Runtime kill-switch to disable the parser entirely. |
Recommended: Docker + tika-pipes
Because this parser loads native code into the JVM, the safest deployment is a Docker container running tika-pipes with forked JVMs. If the native code crashes, only the fork dies — tika-pipes will respawn it automatically.
A minimal Dockerfile:
FROM eclipse-temurin:21-jre
RUN apt-get update && \
apt-get install -y --no-install-recommends \
libtesseract-dev \
libleptonica-dev \
tesseract-ocr-eng && \
rm -rf /var/lib/apt/lists/*
# Copy your tika-pipes application and config
COPY target/tika-pipes-app.jar /app/tika-pipes-app.jar
COPY tika-config.json /app/tika-config.json
WORKDIR /app
ENTRYPOINT ["java", "-jar", "tika-pipes-app.jar"]
Use the basic configuration above with those container paths.
Set poolSize equal to the number of forked parser threads to
maximize throughput without over-allocating native memory.
|
Tess4J vs. TesseractOCRParser
| Aspect | TesseractOCRParser |
Tess4JParser |
|---|---|---|
How it calls Tesseract |
Spawns a new |
Calls the native library in-process via JNA |
Startup overhead |
Process fork + exec per file |
One-time JNA initialization; pooled thereafter |
Thread safety |
Naturally safe (separate processes) |
Safe via pooled instances |
Crash isolation |
Child process crashes do not affect the JVM |
A native crash will take down the JVM |
Dependencies |
|
|
Best for |
Safety-first deployments, light OCR workloads |
High-throughput batch processing in Docker / tika-pipes |
Per-request configuration
In-process, place a Tess4JConfig on the ParseContext:
Tess4JConfig override = new Tess4JConfig();
override.setLanguage("fra");
override.setPageSegMode(6);
ParseContext context = new ParseContext();
context.set(Tess4JConfig.class, override);
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.
|