Apache Tika 4.0 来了:Java文件解析的唯一答案

如果你在做「上传 → 解析 → 切片 → 向量化 → 检索」,Tika 卡在第一段。第一段不稳,后面模型再强也是垃圾进、垃圾出。

用户甩过来的不是干净 JSON,是 PDF、docx、xlsx、邮件、扫描件,以及压缩包套压缩包。

Java 里你当然可以给每种格式各找一个库。PDF 一套,Office 一套,HTML 再一套。项目活下来的第三个月,依赖树会开始报复你:版本冲突,传递依赖,某个月突然冒出来的 CVE。有人坚持「只支持我们认可的三种格式」,那是产品能力;更多业务方会说,客户发什么,你就得吃什么。

4.0 新特性

1. 解析能力插件化

3.x 的 tika-app.jar 是那种丢哪都能 java -jar 的胖包。4.x 不这么干了。

官方可运行产物改成 Zip:解压后是轻量 launcher,旁边摆着 lib/plugins/。只拷贝单个 jar 去跑,多半直接 NoClassDefFoundError

管道扩展(tika-pipes 那一类)走 PF4J,插件打成 zip 丢进 plugins/。类加载边界更干净,Jackson 在插件和宿主之间打架的概率会小一截。需要临时塞自定义检测器或解析器时,还可以用 -Dtika.extras.dir 指到一个受信任目录,启动时加载额外 jar,fork 出去的 pipes 子进程也会带上。

2. 配置从 XML 换成 JSON

tika-config.xml 在 4.x 不再受支持,换成 tika-config.json

组件不再写全限定类名,改成 kebab-case 短名,比如 pdf-parser。名字由编译期 @TikaComponent 索引生成,运行时少靠反射扫世界。云原生环境里,JSON 也比 XML 更好进 ConfigMap、更好 diff。

有转换命令:

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

3. API 入口:TikaConfig 换成 TikaLoader

Java 代码里,org.apache.tika.config.TikaConfig 没了。自定义配置请用 tika-serialization 里的 TikaLoader

1
2
3
4
5
6
7
// 默认 SPI 发现
TikaLoader loader = TikaLoader.loadDefault(getClass().getClassLoader());

// 或读 JSON
TikaLoader loader = TikaLoader.load(Path.of("tika-config.json"));

Parser autoDetect = loader.loadAutoDetectParser();

如果你一直用 new Tika()DefaultParser 做简单抽取,这条路径大体还能用。不必一上来就重写半个项目。真正麻烦的,是你们当年为了调 PDF 参数塞进去的那坨 XML,以及 server 客户端写死的旧路径。

4. 默认输出改成 Markdown

这一条看起来像排版偏好,其实是产品立场。

4.x 里,tika-apptika-server/tika/rmeta、以及 pipes/async CLI,默认内容处理器从 XHTML/XML 切到了 Markdown。

Markdown 还留着标题、列表、表格这些结构,标签却比 XHTML 轻。切块喂向量库、塞进模型上下文,都更顺手。以前你得自己把一坨标签洗成人话;现在默认更接近「能直接切」的样子。对 token 账单敏感的人,会喜欢这个默认值。

5. 安全能力增强

分布式场景里,Tika 一直在补两类坑:配置反序列化被滥用,以及用户字段盖掉系统元数据。

4.x 的方向比较明确:

  • 初始化配置当可信源;运行时动态配置走更严的白名单,失败就关(fail-closed)
  • 用户侧或内部合成的元数据键加命名空间前缀,降低覆盖风险
  • tika-server 把「一把梭的 unsecure 开关」拆成 allowPipesallowPerRequestConfig 等更细的门闩,默认更接近拒绝

server API 也更「路径即契约」:旧 form 端点、靠 Accept 头猜格式的路由在收缩,改成 /tika/text/tika/json 这类显式路径。错误响应趋向结构化 JSON,而不是一坨纯文本。对写客户端的人,短期是 breaking change;长期是少猜。

哪些是 AI 相关的?

tika-dl 这类旧深度学习模块在 4.x 被移除。信号很清楚:核心里不再绑重型本地 DL 依赖,把「看图读字」交给可替换的外部 VLM 端点。方向从「内嵌模型」改成「外挂模型」。

能力 算不算 AI 说明
VLM Parser(OpenAI/Claude/Gemini) 远程多模态理解 / OCR++
默认 Markdown 输出 半是 服务 LLM 输入,本身无模型
旧 tika-dl 已移除 旧本地 DL 路线退出
Tesseract / Tess4J OCR 传统 CV 仍可用,可和 VLM 组合
千种格式统一抽取 基础设施 RAG 上游,不是生成模型

VLM 解析器

4.x 在 tika-parser-vlm-ocr-module 里给了一组 VLM(Vision-Language Model)Parser。套路不是本地再塞一个深度学习胖包,而是把图或 PDF 丢给远程多模态接口,拿回 Markdown,再转成 Tika 内部结构。

三套开箱实现:

解析器 对接 配置键 SPI 默认加载
OpenAIVLMParser OpenAI 兼容 Chat Completions(vLLM / Ollama / LocalAI / 官方 API) openai-vlm-parser
ClaudeVLMParser Anthropic Messages API claude-vlm-parser 否,需显式配置
GeminiVLMParser Google Gemini generateContent gemini-vlm-parser 否,需显式配置

Claude / Gemini 还声明了对 application/pdf 的原生支持,可以把整份 PDF 当视觉文档扔给模型。Tesseract 更擅长「认字」;复杂版式、表格、扫描合同,VLM 往往更像「读文档」。两者不是互相替代,是可组合:普通数字 PDF 走本地解析,扫图页再打 VLM,成本会理智很多。

最小配置长这样(百炼 DashScope 的 qwen-vl-max):

1
2
3
4
5
6
7
8
9
10
11
12
{
"parsers": [
{
"openai-vlm-parser": {
"baseUrl": "https://dashscope.aliyuncs.com/compatible-mode/v1",
"model": "qwen-vl-max",
"apiKey": "${DASHSCOPE_API_KEY}",
"timeoutSeconds": 300
}
}
]
}

对已经在 Java 里堆 RAG 的人,这比「再写一个 Python sidecar 专吃扫描件」省心。

总结

工程上,Tika 4.0 在卸历史包袱:胖 JAR、XML 配置、过宽的 server 能力、脆弱的序列化边界,一件件往外扔。AI 这块,它没把模型焊进核心,只是加了 VLM 外包接口,顺手把默认输出改成更适合大模型管线的 Markdown。