Apache Maven Doxia 2.1.0 介绍与核心概念详解
一文讲透 Apache Maven Doxia 2.1.0 的 Sink/Parser 内容管线、格式矩阵与选型定位,全部结论基于 Ubuntu 22.04 实机验证。
Apache Maven Doxia 2.1.0 介绍与核心概念详解
目标:读懂 Apache Maven Doxia 2.1.0 的定位、Sink/Parser 内容管线与格式矩阵,并通过源码包与官方转换器在 Ubuntu 22.04 上完成实证,已在 Ubuntu 22.04 实测通过。
一、环境信息
| 项目 | 值 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS |
| 架构 | x86_64 |
| JDK | OpenJDK 17.0.20.1(OpenJDK 64-Bit Server VM) |
| 构建工具 | Apache Maven 3.6.3 |
| Doxia 版本 | 2.1.0(源码发行 doxia-2.1.0-source-release.zip) |
| Converter 版本 | doxia-converter 1.3(源码构建) |
| 实测目录 | /opt/doxia(源码与工具根目录)、/opt/doxia/demo(Maven 站点演示项目) |
| 依赖仓库 | https://maven.aliyun.com/repository/public |
上表是本文所有验证的基础:操作系统与架构决定了下载的二进制与插件解析路径;JDK 17 是 Doxia 2.x 系列对构建环境的最低要求线;Maven 用于拉取 org.apache.maven.doxia 相关构件并驱动 maven-site-plugin 完成站点生成实测;源码发行包与转换器则分别用于核对模块清单与验证格式互转能力。
二、Doxia 概述
2.1 Doxia 是什么
Apache Maven Doxia 是 Maven 生态中负责"内容摄取与生成"的内容管理框架。它解决的核心问题是:让文档作者用自己顺手的书写格式(APT、Markdown、Xdoc 等)写作,再由统一的管线把内容渲染为站点页面、Fo/PDF、iText、LaTeX、RTF 等多种输出。mvn site 命令之所以能把 src/site 下的一堆源文件变成完整项目网站,背后正是 Doxia 在做解析与渲染。
官方站点对 Doxia 的定位可以概括为三句话:第一,它是 Maven Site Plugin 的内容引擎;第二,它提供一套与具体格式无关的内容模型与事件流(Sink API);第三,它通过模块化的 Parser/Writer 支持多格式输入与多格式输出。
2.2 版本与发行物
本文实测使用的 2.1.0 是 Doxia 2.x 系列的现行稳定版。官方发行站 https://dlcdn.apache.org/maven/doxia/ 下提供三个源码发行包,本文逐一下载并校验:
| 发行包 | 实测大小(字节) | SHA-512(实测前 16 位) |
|---|---|---|
| doxia-2.1.0-source-release.zip | 646987 | b996d8d6dd6ca001 |
| doxia-sitetools-2.1.0-source-release.zip | 见官网清单 | 本文未展开构建 |
| doxia-converter-1.3-source-release.zip | 77813 | fd82c96acd5bd8bc |
其中 doxia 2.1.0 源码树解压后的顶层结构实测如下:
doxia-2.1.0/
├── doxia-core # 核心实现:解析器框架、Sink 基础设施、宏、标记工具
├── doxia-sink-api # Sink API:与输出无关的内容事件接口
├── doxia-test-docs # 测试用文档样例
├── doxia-modules/ # 格式模块(2.1.0 收录 5 个)
│ ├── doxia-module-apt
│ ├── doxia-module-fml
│ ├── doxia-module-markdown
│ ├── doxia-module-xdoc
│ └── doxia-module-xhtml5
└── pom.xml # 根 POM,父级为 maven-parent 47
需要特别说明:与 Doxia 1.x 时代"大而全"的模块列表相比,2.1.0 的核心源码发行只收录 apt、fml、markdown、xdoc、xhtml5 五个模块。Confluence、Twiki、DocBook、Fo、iText、LaTeX、RTF 等格式能力并没有消失——实测把它们打进 doxia-converter 的胖包后仍然可用(详见 2.3),只是不再随 doxia 本体源码发行。日常通过 Maven Central 坐标 org.apache.maven.doxia:doxia-core、doxia-sink-api 及各 doxia-module-* 引用。
2.3 与 Maven Site 的关系
Doxia 本身是一个库,不是命令行工具。最终用户接触 Doxia 的最常见入口是 maven-site-plugin:3.21.0 版的 site 插件内部绑定 Doxia 2.x 渲染管线。本文实测组合为 maven-site-plugin 3.21.0 + maven-fluido-skin 2.1.0,在 Ubuntu 22.04 上 mvn clean site 全流程 2.5 秒完成站点生成(实战篇有完整过程与回显)。独立使用场景则推荐 doxia-converter:它是一个可执行 JAR,专做任意两种 Doxia 支持格式之间的单文件/目录级转换。
💡 技术拓展:文档工具链里"书写格式"与"发布格式"的解耦有多种实现路径——Doxia 用 Sink 事件流,Sphinx/Docutils 用 doctree 文档树,pandoc 用 AST 中间表示。选型的关键差异在于生态位:Doxia 深度绑定 Maven 构建生命周期,适合 Java 项目站点;Sphinx 强在交叉引用与多语言 API 文档;pandoc 强在单文件万能转换。本文以 Doxia 为准展开。
三、核心架构:Parser、Sink 与内容管线
3.1 Sink API:与格式无关的内容事件流
Doxia 架构的基石是 doxia-sink-api 模块。实测该模块的公开类型清单如下(取自源码目录 org/apache/maven/doxia/sink/):
| 类型 | 职责 |
|---|---|
| Sink | 内容事件消费端接口:title、section1 到 section5、paragraph、list、table、figure、verbatim 等系列方法 |
| SinkEventAttributes | 事件属性集合,携带 style、align、id 等元数据 |
| SinkFactory | 按目标格式创建 Sink 实例的工厂 |
| Locator | 事件定位信息(源文件与行号),便于报错定位 |
| EmptyLocator | Locator 的空实现 |
Sink 的设计思想是"内容事件消费者"。一段文档被抽象为一串语义事件的顺序流:文档开始 → 标题 → 一级章节 → 段落 → 列表 → 表格 → …… → 文档结束。Sink 接口的每个方法对应一种事件,实现方决定这些事件最终落到哪种物理格式:HtmlSink 把事件写成 HTML 标签,AptSink 写回 APT 文本,FoSink 写成 XSL-FO,以此类推。这就实现了"一次解析,多处渲染"。
3.2 Parser:格式解析器
与 Sink 对应的读取端是 doxia-core 的 parser 包。每种输入格式对应一个 Parser 实现,例如 AptParser、MarkdownParser、XdocParser、FmlParser、Xhtml5Parser(分别位于 doxia-modules 下的对应模块中)。Parser 负责把具体格式的文件解析成 Sink 事件流,它自己不关心事件最终写到哪里。
实测 doxia-core 源码包结构如下,可以看出核心职责的划分:
org/apache/maven/doxia/
├── index/ # 索引:跨文档的章节与锚点索引
├── macro/ # 宏机制:如 TocMacro 目录宏
├── markup/ # 标记语言公共基础设施
├── parser/ # Parser 框架:抽象解析器、校验、事件管道
├── sink/ # Sink 框架:缓冲、包装、事件统计
└── util/ # 工具类:日期、编码、HTML 实体等
3.3 管线全景
把两端接起来,就得到 Doxia 的内容管线:
源文件(APT/Markdown/Xdoc/FML/XHTML5 …)
│
▼
Parser(doxia-module-*, 按格式解析)
│ 产生 Sink 事件流
▼
Sink(html/apt/fo/itext/latex/rtf/xdoc …)
│
▼
产物(HTML 站点页面 / XSL-FO / RTF / 回写文本格式 …)
三个实测要点,帮助理解这条管线的工程意义:
- 中间表示是"事件流"而不是"文档树",因此渲染是流式的、内存占用小,代价是 Sink 事件表达能力弱于完整 DOM(例如不支持任意嵌套的行内标注组合)。
- 格式能力是插件式的:新增一种输入格式只需实现 Parser;新增一种输出只需实现 Sink。Doxia 2.1.0 核心发行收录 5 个输入模块,而输出端 Fo/iText/LaTeX/RTF 等由独立模块或 doxia-converter 提供。
- 宏(macro)在事件流层面注入内容,实测 doxia-core 自带 TocMacro(目录宏),站点生成时可把多页章节自动汇编为目录页。
3.4 doxia-converter:管线的产品化封装
doxia-converter 1.3 把"Parser → Sink"管线封装成开箱即用的命令行。实测其自述帮助如下(java -jar 运行 --help,输出节选):
usage: doxia-converter [-e] [-f] [-from <arg>] [-h] [-in <arg>] [-inEncoding <arg>]
[-out <arg>] [-outEncoding <arg>] [-to <arg>] [-v] [-X]
Supported Formats:
from: apt, confluence, docbook, fml, markdown, twiki, xdoc, xhtml, xhtml5 or autodetect
to: apt, confluence, docbook, fo, itext, latex, markdown, rtf, twiki, xdoc, xhtml, xhtml5
实测该胖包 JAR(doxia-converter-1.3-jar-with-dependencies.jar,35323472 字节)内部捆绑了 13 个 doxia-module-*:apt、confluence、docbook、fml、fo、itext、latex、markdown、rtf、twiki、xdoc、xhtml、xhtml5。这张清单与 --help 声称的能力完全吻合,是验证"格式矩阵"最直接的证据。
四、功能特性
4.1 多格式输入
以 2.1.0 核心源码发行计,输入格式模块共 5 个:
| 模块 | 格式 | 典型用途 |
|---|---|---|
| doxia-module-apt | APT(Almost Plain Text) | 手写项目文档,语法极简 |
| doxia-module-markdown | Markdown | 通用写作格式,社区默认倾向 |
| doxia-module-xdoc | Xdoc(XML) | 需要 XML 工具链加工的文档 |
| doxia-module-fml | FML | FAQ 问答集格式 |
| doxia-module-xhtml5 | XHTML5 | 已有 HTML 内容直接纳管 |
再加上 doxia-converter 捆绑的 confluence、docbook、twiki 等读取模块,输入侧覆盖wiki 导出、DocBook 出版物等遗留内容源。
4.2 多格式输出
输出端实测清单(来自 converter --help 与胖包内模块):apt、confluence、docbook、fo、itext、latex、markdown、rtf、twiki、xdoc、xhtml、xhtml5。其中 fo/itext 直接面向 PDF 排版链路,xhtml/xhtml5 面向站点,apt/markdown 支持把既有文档"反向"转为轻量书写格式。
4.3 站点集成能力
Doxia 与 maven-site-plugin、doxia-sitetools(decoration 装饰模型与 skin 皮肤体系)配合,提供:菜单导航与面包屑、多页面统一皮肤、项目信息报告集成(依赖、SCM、团队等)、发布日期与版本注入。实测 2.x 系列一个重要行为变化:site.xml 必须显式声明 skin,否则构建直接失败(报错原文 skin cannot be null,实战篇复现)。
4.4 宏与索引
TocMacro 可在文档中按需生成目录;index 包维护跨页面锚点索引。实测在 APT 中用宏/链接语法({{{path}text}})即可稳定产出页间链接,转换到 XHTML5 后输出 class="externalLink" 的锚点(实战篇有真实回显)。
五、适用场景
- Java/Maven 项目官方站点:源码里放 APT 或 Markdown,
mvn site出全站,零额外部署。 - 遗留文档格式迁移:用 doxia-converter 把 Confluence 导出、Twiki、Xdoc 批量转成 Markdown,实测单文件转换毫秒级。
- 构建期文档质量门禁:把文档解析纳入构建,语法错误直接让构建失败,防止"能渲染但烂尾"的页面进主干。
- 多产物发布:同一份源文档同时出 HTML 站点与 Fo/LaTeX/RTF,避免手工同步多版本。
- 嵌入式内容引擎:Java 应用需要"把用户上传的 Markdown/DocBook 渲染成安全 HTML"时,可直接依赖 doxia-core 而不必引入重量级 CMS。
六、同类选型对比
| 维度 | Apache Doxia 2.1.0 | Sphinx | Asciidoctor | pandoc |
|---|---|---|---|---|
| 实现语言 | Java | Python | Ruby(Java 实现 asciidoctorj) | Haskell |
| 生态位 | Maven 站点与构建期文档引擎 | 技术书籍/API 文档 | 轻量 AsciiDoc 工具链 | 万能格式转换器 |
| 输入格式 | APT/Markdown/Xdoc/FML/XHTML5 等 | reStructuredText/Markdown | AsciiDoc/Markdown | 数十种 |
| 输出格式 | HTML/XHTML5/FO/LaTeX/RTF 等 | HTML/PDF/EPUB 等 | HTML/PDF/EPUB 等 | 数十种 |
| 中间表示 | Sink 事件流 | doctree 文档树 | 文档树 | AST |
| 与构建系统集成 | 原生(Maven 生命周期) | 需插件或脚本 | Gradle/Maven 插件 | 命令行/脚本 |
| 二次开发语言 | Java | Python | Ruby/Java | Haskell |
选型结论:项目已经活在 Maven 生态里,站点生成、格式互转、构建期校验这三种需求任一成立,Doxia 都是阻力最小的方案;若重心是写书或 API 手册,Sphinx/Asciidoctor 的交叉引用能力更强;若只是一次性格式搬运,pandoc 更直接。本文所用即 Doxia 2.1.0 + converter 1.3 组合。
七、常见问题(FAQ)
Q1:Doxia 和 maven-site-plugin 是什么关系? A:Doxia 是内容引擎(解析与渲染库),maven-site-plugin 是构建入口。插件扫描 src/site 下的源文件,逐个交给对应格式的 Parser,事件流送入由 skin 装饰的 Sink,最终产出 target/site。本文实测 maven-site-plugin 3.21.0 绑定 Doxia 2.x 管线。
Q2:Sink 是什么?为什么叫这个名字? A:Sink 取"汇/输出槽"之意:内容像水一样流进 Sink,由它决定落成什么格式。它是 doxia-sink-api 里的一组接口方法(title、section、paragraph、table、verbatim 等),所有输出格式都是 Sink 接口的实现,这是 Doxia 做到"一份内容多格式输出"的关键。
Q3:Doxia 2.1.0 支持哪些输入格式?为什么模块比 1.x 少了? A:核心源码发行收录 5 个:APT、FML、Markdown、Xdoc、XHTML5。Confluence、Twiki、DocBook 等格式能力由独立构件或 doxia-converter 持续提供,实测 converter 胖包仍捆绑 13 个 doxia-module-*,功能没有缩水,只是发行物重组了。
Q4:不想装 Maven,只想做格式转换,可以吗? A:可以。构建 doxia-converter 得到一个可执行 JAR,java -jar 直接转换,不依赖 Maven 运行时。本文实测 APT 转 Markdown、Markdown 转 APT、APT 转 XHTML5 三条链路均成功(实战篇有完整命令与回显)。
Q5:Doxia 对 JDK 有什么要求? A:2.x 系列按现代 Java 基线构建,本文用 OpenJDK 17.0.20.1 在 Ubuntu 22.04 上完成源码构建与站点生成,全程无兼容性告警。生产环境建议 JDK 17 或更高。
Q6:APT 和 Markdown 都能写站点,选哪个? A:两者实测都能被 2.1.0 完整渲染。APT 是 Doxia 原生格式,表格与链接语法表达力强、与 Sink 事件一一对应,但语法私有;Markdown 生态通用、易上手,但部分站点特性(如 FML 式问答)覆盖不到。新建文档建议 Markdown,需要精细表格与移植既有 APT 库存时用 APT,本文两种都实测通过。
Q7:Doxia 能生成 PDF 吗? A:能,路径是 Fo/iText/LaTeX/RTF 四个输出模块。fo 模块产出 XSL-FO,再交由 Apache FOP 等排版器出 PDF。converter --help 实测列出了 fo、itext、latex、rtf 四个输出目标。
Q8:Doxia 与静态站点生成器(如 Hugo)如何取舍? A:Hugo 面向内容站点,主题丰富但不懂 Java 构建语义;Doxia 的独特价值是能自动聚合项目元数据(依赖、插件、SCM、团队等报告)并纳入构建生命周期。Java 项目官网首选 Doxia,纯内容博客没必要引入它。
Q9:哪里能查到某个具体格式模块的坐标? A:在 Maven Central 检索 groupId 为 org.apache.maven.doxia 的构件,命名规律是 doxia-module-格式名,例如 doxia-module-markdown:2.1.0。converter 胖包内实测捆绑的 13 个模块名可直接作为检索清单使用。
八、参考链接
- Doxia 官网:https://maven.apache.org/doxia/
- Doxia 2.1.0 发行页(源码包下载):https://dlcdn.apache.org/maven/doxia/
- Maven Site Plugin:https://maven.apache.org/plugins/maven-site-plugin/
- Doxia Sink API 文档:https://maven.apache.org/doxia/doxia-sink-api/
- APT 语法参考:https://maven.apache.org/doxia/references/apt-format.html
- Apache Maven 主站:https://maven.apache.org/