Tess4J OCR Parser
|
Advanced users only. If that doesn’t describe you, don’t reach for this parser — and that’s perfectly fine.
|
Component name: tess4j-parser. Adding tika-parser-tess4j-module to the classpath is a
deliberate opt-in and is intended to make Tess4J the OCR engine — but when both engines are
live, the winner is decided by registration order, which is not guaranteed. Since 4.1.0 a WARN
at startup names the collision and the winner; to pin the engine deterministically, name it in
the top-level text-recognizers list (tess4j-parser or tesseract-ocr-parser; see
Configuration).
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</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
{
"text-recognizers": [
{
"tess4j-parser": {
"dataPath": "/usr/share/tesseract-ocr/5/tessdata",
"nativeLibPath": "/usr/lib/x86_64-linux-gnu",
"poolSize": 4
}
}
]
}
Full Configuration
{
"text-recognizers": [
{
"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. 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.
|