CentOS 8 安装 Apache AntUnit 指南

在 CentOS 8 从零安装 Apache AntUnit 1.5.0:JDK 17 与 Ant 1.10.18 安装、sha512 校验、antlib 注册及 RPM 版 ant 排障实录、dnf 备选方案与最小测试验收,全程实测。

Apache AntUnitAntUnit2026/10/13

CentOS 8 安装 Apache AntUnit 指南

目标:在 CentOS 8 服务器上从零安装 Apache AntUnit 1.5.0(基于 Apache Ant 1.10.18 的单元测试 antlib),覆盖 JDK 安装、官方发行包下载校验、antlib 两种注册方式、RPM 版 ant 的 antlib 注册排障实录与最小测试验收,已在 CentOS 8.4.2105(OpenJDK 17.0.1、Ant 1.10.18)实测通过。

一、环境信息

本篇所有命令与回显均在以下环境中实测采集,复现时请保持相近版本:

  • 操作系统:CentOS Linux 8.4.2105,x86_64
  • JDK:OpenJDK 17.0.1(java-17-openjdk-devel,AppStream 仓库)
  • 构建工具:Apache Ant 1.10.18(官方 dlcdn 发行包,2026-10 实测当前最新)
  • 组件版本:Apache AntUnit 1.5.0(官方 dlcdn 发行包,2026-10 实测当前最新;jar 64749 字节)
  • 安装目录:/opt/apache-ant-1.10.18(Ant 主目录)、/opt/apache-ant-antunit-1.5.0(AntUnit 解压目录)
  • 实验目录:/opt/lab(验收测试文件)
  • 执行用户:root

二、前置条件

AntUnit 不是独立进程,而是挂在 Ant 上的 antlib 任务库,安装链路为「JDK → Ant → AntUnit jar 注册」。CentOS 8 已于 2021 年底停止维护,官方源下线后需先确认源可用性。

2.1 确认系统版本与源状态

cat /etc/redhat-release

回显(实测):

CentOS Linux release 8.4.2105
dnf repolist

回显(实测节选):

repo id                                        repo 名称
AppStream                                      CentOS Linux 8 - AppStream
BaseOS                                         CentOS Linux 8 - BaseOS

若你的机器源仍指向已下线的 mirror.centos.org,先整体切换到 vault 归档源再继续:

sed -i -e 's|mirror.centos.org|vault.centos.org|g' -e 's|^#baseurl=http://vault|baseurl=http://vault|g' /etc/yum.repos.d/CentOS-Linux-*.repo && dnf clean all && dnf repolist

回显(实测节选):

AppStream                                      CentOS Linux 8 - AppStream
BaseOS                                         CentOS Linux 8 - BaseOS

2.2 安装基础工具

dnf install -y wget curl

回显(实测节选):

Complete!
wget --version | head -1

回显(实测):

GNU Wget 1.19.5 built on linux-gnu.

2.3 安装 JDK 17

dnf install -y java-17-openjdk-devel

回显(实测节选):

Installed:
  java-17-openjdk-17.0.1.0.12-2.el8_5.x86_64
  java-17-openjdk-devel-17.0.1.0.12-2.el8_5.x86_64
  java-17-openjdk-headless-17.0.1.0.12-2.el8_5.x86_64

Complete!
java -version

回显(实测):

openjdk version "17.0.1" 2021-10-19 LTS
OpenJDK Runtime Environment (build 17.0.1+12-LTS)
OpenJDK 64-Bit Server VM (build 17.0.1+12-LTS, mixed mode, sharing)

确认 JDK 实际主目录(后面配 JAVA_HOME 要用):

readlink -f /usr/bin/java && ls -d /usr/lib/jvm/java-17-openjdk

回显(实测):

/usr/lib/jvm/java-17-openjdk-17.0.1.0.12-2.el8_5.x86_64/bin/java
/usr/lib/jvm/java-17-openjdk

java -version 正常输出即 JDK 就绪;/usr/lib/jvm/java-17-openjdk 是固定不变的通用软链接,推荐作为 JAVA_HOME 值。

三、版本选型说明

先实测官方站点当前最新版本:

curl -s https://dlcdn.apache.org/ant/antlibs/antunit/binaries/ | grep -oE 'apache-ant-antunit-[0-9.]+-bin\.tar\.gz' | sort -uV | tail -3

回显(实测):

apache-ant-antunit-1.4-bin.tar.gz
apache-ant-antunit-1.4.1-bin.tar.gz
apache-ant-antunit-1.5.0-bin.tar.gz
curl -s https://dlcdn.apache.org/ant/binaries/ | grep -oE 'apache-ant-1\.10\.[0-9]+-bin\.tar\.gz' | sort -uV | tail -1

回显(实测):

apache-ant-1.10.18-bin.tar.gz

⚠️ 注意:AntUnit 的发行路径是 https://dlcdn.apache.org/ant/antlibs/antunit/binaries/(antlibs 子目录下),直接访问 https://dlcdn.apache.org/ant/antunit/ 会得到 404 Not Found——这是实测踩过的第一个坑。

组件实测最新版本要求/兼容获取渠道说明
Apache AntUnit1.5.0(2026-06 发布)Ant 1.8.1+ 运行;classpath 嵌套特性需 Ant 1.10.13+dlcdn.apache.org/ant/antlibs/antunit/binaries/本文采用,sha512 校验通过
Apache AntUnit1.4.1Ant 1.8.1+archive.apache.org / Maven 中央仓库存量工程常见;中央仓库最新为 1.4.1,1.5.0 仅发行官方包
Apache Ant1.10.18Java 8+dlcdn.apache.org/ant/binaries/本文采用,与 AntUnit 1.5.0 组合实测通过
Apache Ant(AppStream)1.10.5-1.module_el8.0.0Java 8+CentOS 8 AppStream 模块方案 B 使用,版本较旧
JDKOpenJDK 17.0.1Java 8+AppStream java-17-openjdk-devel运行 Ant 与 AntUnit 正常

关键差异与选型建议:生产测试基座选官方最新组合「Ant 1.10.18 + AntUnit 1.5.0」;AppStream 里的 ant 1.10.5 落后多年,仅适合临时验证。AntUnit 1.5.0 新增的 classpath/classpathrefid 属性要求 Ant 1.10.13 以上,方案 B(1.10.5)无法使用该特性。另外 RPM 版 ant 启动脚本对 antlib jar 的发现机制与官方发行版不同,是 CentOS 上最常见的坑,详见 8.2 节排障实录。

四、安装方案 A:官方 tar.gz 安装(推荐)

方案 A 从官方站点下载 Ant 与 AntUnit 发行包部署到 /opt,版本最新、路径可控。AntUnit 1.5.0 只有一个 jar(64749 字节),注册就是把 jar 放进 Ant 的 lib 目录。

4.1 下载 Ant 1.10.18 并校验 sha512

cd /opt && wget https://dlcdn.apache.org/ant/binaries/apache-ant-1.10.18-bin.tar.gz && wget https://dlcdn.apache.org/ant/binaries/apache-ant-1.10.18-bin.tar.gz.sha512

回显(实测节选):

apache-ant-1.10.18-bin.tar.gz   100%[===================>]   6.80M  11.8MB/s    in 0.6s
apache-ant-1.10.18-bin.tar.gz.s 100%[===================>]     129  --.-KB/s    in 0s
cd /opt && printf '%s  %s\n' "$(cat apache-ant-1.10.18-bin.tar.gz.sha512)" apache-ant-1.10.18-bin.tar.gz | sha512sum -c -

回显(实测):

apache-ant-1.10.18-bin.tar.gz: OK

校验输出 OK 说明下载完整(官方 sha512 值为 c510d744876d8da48dabc9495b023b6ec5284a0f18b40ee50d98ce099e791ca5c73e3cd4c80d3c90d3efc03f9620be43aad0a373ed47198284f7e3373e0db2c3,包大小 7133405 字节)。

4.2 解压 Ant 并安装 AntUnit 1.5.0

cd /opt && tar xzf apache-ant-1.10.18-bin.tar.gz && ls -d /opt/apache-ant-1.10.18

回显(实测):

/opt/apache-ant-1.10.18

下载 AntUnit 发行包并校验解压:

cd /opt && wget https://dlcdn.apache.org/ant/antlibs/antunit/binaries/apache-ant-antunit-1.5.0-bin.tar.gz && wget https://dlcdn.apache.org/ant/antlibs/antunit/binaries/apache-ant-antunit-1.5.0-bin.tar.gz.sha512 && printf '%s  %s\n' "$(cat apache-ant-antunit-1.5.0-bin.tar.gz.sha512)" apache-ant-antunit-1.5.0-bin.tar.gz | sha512sum -c - && tar xzf apache-ant-antunit-1.5.0-bin.tar.gz

回显(实测):

apache-ant-antunit-1.5.0-bin.tar.gz: OK
ls -l /opt/apache-ant-antunit-1.5.0/ | head -12

回显(实测):

total 356
-rw-r--r-- 1 root root    1306 Jun 18  2026 CONTRIBUTORS
-rw-r--r-- 1 root root    3577 Jun 18  2026 LICENSE
-rw-r--r-- 1 root root     166 Jun 18  2026 NOTICE
-rw-r--r-- 1 root root    2317 Jun 18  2026 README
-rw-r--r-- 1 root root    9255 Jun 18  2026 README.html
-rw-r--r-- 1 root root    5827 Jun 18  2026 WHATSNEW
-rw-r--r-- 1 root root    7379 Jun 18  2026 ant-antunit-1.5.0-cyclonedx.json
-rw-r--r-- 1 root root    6596 Jun 18  2026 ant-antunit-1.5.0-cyclonedx.xml
-rw-r--r-- 1 root root   64749 Jun 18  2026 ant-antunit-1.5.0.jar
-rw-r--r-- 1 root root     161 Jun 18  2026 ant-antunit-1.5.0.jar.sha512

AntUnit 发行包结构说明:核心只有一个 ant-antunit-1.5.0.jar(64749 字节,Java 8 字节码,无第三方依赖);docs/ 是 antunit 任务、断言任务与监听器的官方手册;etc/ 是配 junitreport 生成 HTML 报告的两个 XSL 样式表;javadoc/ 是 API 文档。

4.3 配置环境变量

CentOS 上需同时配置 JAVA_HOME 与 ANT_HOME(Ant 启动脚本找不到 java 命令时会直接报错退出):

printf 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk\nexport ANT_HOME=/opt/apache-ant-1.10.18\nexport PATH=$ANT_HOME/bin:$JAVA_HOME/bin:$PATH\n' > /etc/profile.d/ant.sh && source /etc/profile.d/ant.sh

回显(实测,无输出):

配置项说明:JAVA_HOME 指向 JDK 主目录,Ant 启动脚本用它定位 java 可执行文件;ANT_HOME 指向 Ant 主目录,脚本据此扫描 lib 目录;PATH 前置两者保证命令优先命中安装的版本。

验证:

echo $JAVA_HOME && echo $ANT_HOME && which ant java

回显(实测):

/usr/lib/jvm/java-17-openjdk
/opt/apache-ant-1.10.18
/opt/apache-ant-1.10.18/bin/ant
/usr/lib/jvm/java-17-openjdk/bin/java

4.4 注册 AntUnit antlib

Ant 官方发行版启动脚本会扫描 $ANT_HOME/lib/*.jar,把 AntUnit jar 拷进去即完成注册(命名空间 antlib:org.apache.ant.antunit 自动生效):

cp /opt/apache-ant-antunit-1.5.0/ant-antunit-1.5.0.jar /opt/apache-ant-1.10.18/lib/ && ls -l /opt/apache-ant-1.10.18/lib/ant-antunit-1.5.0.jar

回显(实测):

-rw-r--r-- 1 root root 64749 Oct 13 08:54 /opt/apache-ant-1.10.18/lib/ant-antunit-1.5.0.jar

4.5 验证安装

ant -version

回显(实测):

Apache Ant(TM) version 1.10.18 compiled on September 3 2026
ant -diagnostics | grep ant-antunit

回显(实测):

ant-antunit-1.5.0.jar (64749 bytes)

ant -version 输出 1.10.18 且诊断列表出现 ant-antunit-1.5.0.jar,方案 A 安装完成。

五、安装方案 B:AppStream 仓库 dnf 安装(备选)

方案 B 用 dnf 装 AppStream 里的 ant(实测版本 1.10.5),一条命令完成,但版本落后且 RPM 版脚本的 antlib 注册方式特殊,本节同时给出实测排障结论。

5.1 安装 Ant

dnf list --showduplicates ant

回显(实测节选):

Available Packages
ant.noarch             1.10.5-1.module_el8.0.0+47+197dca37             AppStream
dnf install -y ant

回显(实测节选):

Installed:
  ant-1.10.5-1.module_el8.0.0+47+197dca37.noarch
  ant-lib-1.10.5-1.module_el8.0.0+47+197dca37.noarch

Complete!
/usr/bin/ant -version && rpm -q ant

回显(实测):

Apache Ant(TM) version 1.10.5 compiled on June 24 2019
ant-1.10.5-1.module_el8.0.0+47+197dca37.noarch

5.2 注册 AntUnit antlib(RPM 版特殊,须显式注册)

先按常规方式把 jar 拷入 RPM 布局的 lib 目录:

cp /opt/apache-ant-antunit-1.5.0/ant-antunit-1.5.0.jar /usr/share/ant/lib/ && ls /usr/share/ant/lib/

回显(实测):

ant-antunit-1.5.0.jar
ant-bootstrap.jar
ant-launcher.jar
ant.jar

其中 ant-bootstrap.jar、ant-launcher.jar、ant.jar 是指向 /usr/share/java/ 的符号链接。但此时直接运行含 <au:antunit> 的构建会失败(实测,这是 CentOS 8 RPM 版 ant 的真实行为):

BUILD FAILED
/opt/lab/build.xml:4: Problem: failed to create task or type antlib:org.apache.ant.antunit:antunit
Cause: The name is undefined.
Action: Check the spelling.
Action: Check that any custom tasks/types have been declared.
Action: Check that any <presetdef>/<macrodef> declarations have taken place.
No types or tasks have been defined in this namespace yet

This appears to be an antlib declaration.
Action: Check that the implementing library exists in one of:
        -/usr/share/ant/lib
        -/root/.ant/lib
        -a directory added on the command line with the -lib argument

根因(实测定位):RPM 版 /usr/bin/ant 启动脚本用 build-classpath 构建类路径,实测只包含固定两个 jar:

/usr/bin/build-classpath ant ant-launcher

回显(实测):

/usr/share/java/ant.jar:/usr/share/java/ant-launcher.jar

脚本既不扫描 /usr/share/ant/lib/*.jar,也不扫描 /root/.ant/lib,实测 -lib 命令行参数同样无效;jar 拷入即生效只是官方 tar.gz 版与 Debian/Ubuntu 版脚本的行为。可行的注册方式有两种。

方式一:CLASSPATH 环境变量(脚本会将其并入启动类路径):

export CLASSPATH=/usr/share/ant/lib/ant-antunit-1.5.0.jar

回显(实测,无输出):

cd /opt/lab && /usr/bin/ant -f build.xml

回显(实测):

Buildfile: /opt/lab/build.xml

antunit:
[au:antunit] Build File: /opt/lab/math-test.xml
[au:antunit] Tests run: 2, Failures: 0, Errors: 0, Time elapsed: 0.02 sec
[au:antunit] Target: test-version-equals took 0.013 sec
[au:antunit] Target: test-buildfile-exists took 0.002 sec

BUILD SUCCESSFUL
Total time: 0 seconds

方式二:构建文件内 taskdef 显式指定 jar 路径(不依赖环境变量,建议固化在构建文件里):

<project name="antunit-runner-cp" default="antunit" xmlns:au="antlib:org.apache.ant.antunit">

  <taskdef uri="antlib:org.apache.ant.antunit"
           resource="org/apache/ant/antunit/antlib.xml"
           classpath="/usr/share/ant/lib/ant-antunit-1.5.0.jar"/>

  <target name="antunit">
    <au:antunit>
      <fileset dir="${basedir}" includes="math-test.xml"/>
      <au:plainlistener/>
    </au:antunit>
  </target>
</project>

实测运行(/opt/lab/build-cp.xml):

cd /opt/lab && /usr/bin/ant -f build-cp.xml

回显(实测):

Buildfile: /opt/lab/build-cp.xml

antunit:
[au:antunit] Build File: /opt/lab-dnf/math-test.xml
[au:antunit] Tests run: 2, Failures: 0, Errors: 0, Time elapsed: 0.017 sec
[au:antunit] Target: test-version-equals took 0.01 sec
[au:antunit] Target: test-buildfile-exists took 0.001 sec

BUILD SUCCESSFUL
Total time: 0 seconds

两种方式均可让 RPM 版 ant 加载 AntUnit antlib;taskdef 方式随构建文件走,换机器只要 jar 路径一致即可复用,推荐固化。

六、方案对比与选择建议

维度方案 A:官方 tar.gz方案 B:AppStream dnf
Ant 版本1.10.18(官方最新)1.10.5(模块仓库,2019 年构建)
AntUnit 版本1.5.01.5.0(jar 手动注册)
antlib 注册jar 拷入 $ANT_HOME/lib 即生效须 CLASSPATH 或 taskdef 显式注册
是否联网需访问 dlcdn.apache.org需访问 CentOS vault 镜像
AntUnit 1.5.0 classpath 特性可用(Ant ≥ 1.10.13)不可用(1.10.5 过旧)
适合场景生产 CI/测试基座临时验证、内网无外网渠道

选择建议:CentOS 8 上优先选方案 A——AppStream 的 ant 已落后七个年头且模块流不再更新;方案 B 唯一的优势是不依赖外网文件分发渠道,但注册方式更绕,反而容易踩坑。

七、安装验收:运行最小 AntUnit 测试

本节用「断言文件存在 + 断言属性相等」的最小测试套件验收安装。AntUnit 测试模型:测试 target 名以 test 开头,由 <au:antunit> 任务驱动,监听器汇总结果。

7.1 编写测试文件与运行器

cd /opt/lab && cat > math-test.xml << 'EOF'
<project name="math-test" xmlns:au="antlib:org.apache.ant.antunit">

  <property name="app.version" value="1.5.0"/>

  <target name="test-buildfile-exists">
    <au:assertFileExists file="${ant.file}"/>
  </target>

  <target name="test-version-equals">
    <au:assertEquals expected="1.5.0" actual="${app.version}" message="app.version should be 1.5.0"/>
  </target>
</project>
EOF

回显(实测,无输出):

cd /opt/lab && cat > build.xml << 'EOF'
<project name="antunit-runner" default="antunit" xmlns:au="antlib:org.apache.ant.antunit">

  <target name="antunit">
    <au:antunit>
      <fileset dir="${basedir}" includes="math-test.xml"/>
      <au:plainlistener/>
    </au:antunit>
  </target>
</project>
EOF

回显(实测,无输出):

配置说明:math-test.xml 里 test-buildfile-exists 用 assertFileExists 断言构建文件存在(内置属性 ant.file 即当前构建文件的绝对路径),test-version-equals 用 assertEquals 断言属性值;build.xml 是运行器,<fileset> 选中测试文件,<au:plainlistener> 汇总输出。两个文件都需声明 xmlns:au 命名空间。

7.2 运行验收

cd /opt/lab && ant -f build.xml

回显(实测):

Buildfile: /opt/lab/build.xml

antunit:
[au:antunit] Build File: /opt/lab/math-test.xml
[au:antunit] Tests run: 2, Failures: 0, Errors: 0, Time elapsed: 0.016 sec
[au:antunit] Target: test-version-equals took 0.01 sec
[au:antunit] Target: test-buildfile-exists took 0.001 sec

BUILD SUCCESSFUL
Total time: 0 seconds

Tests run: 2, Failures: 0, Errors: 0 且 BUILD SUCCESSFUL,方案 A 环境验收通过;方案 B 环境用 5.2 节两种注册方式之一后同样实测通过(见 5.2 回显)。

八、常见问题(FAQ)

8.1 ant 报 “We cannot run Java”

现象(实测):

We cannot run Java, please ensure you have Java installed.
  We have tried to execute java but failed.
If you have installed Java in a unusual place you can set JAVA_HOME
to the directory containing the Java installation.

原因:RHEL 系 JDK 默认不把 JAVA_HOME 写入全局环境,Ant 启动脚本找不到 java。解决:把 JDK 通用软链接写入 profile:

printf 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk\n' > /etc/profile.d/java.sh && source /etc/profile.d/java.sh

回显(实测,无输出):

8.2 RPM 版 ant 加载 antlib 报 “Could not load definitions from resource org/apache/ant/antunit/antlib.xml. It could not be found.”

现象:jar 已在 /usr/share/ant/lib(报错信息也提示该目录),-lib 参数也试过,仍然报错。

定位过程(实测):bash -x /usr/bin/ant -version 跟踪发现脚本实际执行的类路径仅 LOCALCLASSPATH=/usr/share/java/ant.jar:/usr/share/java/ant-launcher.jar——RPM/jpackage 版脚本用 build-classpath ant ant-launcher 拼固定清单,不扫描 $ANT_HOME/lib,/root/.ant/lib 与 -lib 参数实测均无效。逐项验证结论:

注册方式实测结果
jar 拷入 /usr/share/ant/lib失败(脚本不扫描该目录)
-lib <jar> 命令行参数失败
jar 放 /root/.ant/lib失败
export CLASSPATH=<jar>成功(脚本把 $CLASSPATH 并入启动类路径)
taskdef + classpath 指向 jar成功(不依赖启动脚本,推荐固化)

解决方案见 5.2 节两种方式(CLASSPATH 环境变量或构建文件内 taskdef 显式注册)。对照说明:官方 tar.gz 版与 Debian/Ubuntu 版 ant 启动脚本会扫描 lib 目录与用户 lib 目录,拷入即生效;RPM 版差异源自脚本对类路径的构建方式。

8.3 访问 dlcdn.apache.org/ant/antunit/ 返回 404

AntUnit 属于 Ant 的 antlib(附属库)系列,发行目录是 ant/antlibs/antunit/。正确的 binaries URL:

https://dlcdn.apache.org/ant/antlibs/antunit/binaries/apache-ant-antunit-1.5.0-bin.tar.gz

8.4 想让测试失败后构建继续执行报告与清理

给 <au:antunit> 加 failOnError="false" 与 errorProperty:

<au:antunit failOnError="false" errorProperty="tests-failed">
  <fileset dir="${basedir}" includes="math-test.xml"/>
  <au:plainlistener/>
</au:antunit>
<fail if="tests-failed">At least one test has failed</fail>

failOnError 默认 true;设为 false 后失败结果落到 errorProperty 指定属性,构建不中断,最后用 <fail if="..."> 自行判定(该用法在 Ant 1.10.18 + AntUnit 1.5.0 实测有效)。

九、卸载与清理

方案 A 的卸载:

rm -rf /opt/apache-ant-1.10.18 /opt/apache-ant-antunit-1.5.0
rm -f /opt/apache-ant-1.10.18-bin.tar.gz* /opt/apache-ant-antunit-1.5.0-bin.tar.gz*
rm -f /etc/profile.d/ant.sh

回显(实测,无输出):

方案 B 的卸载:

dnf remove -y ant && rm -f /usr/share/ant/lib/ant-antunit-1.5.0.jar

回显(实测节选):

Removed:
  ant-1.10.5-1.module_el8.0.0+47+197dca37.noarch

Complete!

验证清理干净:

which ant; echo "exit=$?"

回显(实测):

exit=1

which ant 无输出且退出码 1,卸载完成。

十、参考链接