Apache Props Ant Library 1.0.0 快速入门与集成示例
用 10 分钟在独立 Ant 与 Maven 两条路线上跑通 Apache Props Ant Library 1.0.0 的第一个属性展开程序,覆盖构件校验、四种装载方式实测对比与高频坑排障,全部已在 Ubuntu 22.04 实测并跨环境交叉验证。
Apache Props Ant Library 1.0.0 快速入门与集成示例
目标:10 分钟内在独立 Ant 与 Maven(maven-antrun-plugin)两条路线上跑通 Apache Props Ant Library 1.0.0 的第一个属性展开程序,掌握 jar 装载的四种方式与实测差异,并排掉 typedef、propertyhelper、编码三类高频坑。以下全部命令与回显均已在 Ubuntu 22.04(x86_64)、OpenJDK 17.0.20.1 实测通过,并在 CentOS 8 与官方 Ant 1.10.18 环境交叉验证。
一、环境信息
本文所有命令与回显均在以下环境实测采集:
| 项目 | 值 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS(x86_64) |
| 内核 | Linux 6.8.0-138-generic |
| JDK | OpenJDK 17.0.20.1(apt 包 openjdk-17-jdk) |
| Ant | Apache Ant 1.10.12(apt 包 ant) |
| Maven | Apache Maven 3.6.3(apt 包 maven) |
| Props Ant Library | org.apache.ant:ant-props:1.0.0(jar 33260 字节,SHA-1 da89e11da0ab59ce1b1ea5e79a220f98a73c5792) |
| 实验目录 | /opt/props-antlib(构件存放)、/root/props-demo(独立 Ant 工程)、/root/props-maven-demo(Maven 工程) |
| 交叉验证环境 | CentOS 8(Ant 1.10.5、Maven 3.5.4、JDK 17.0.1);另一台 Ubuntu 22.04 服务器(Apache 官方二进制 Ant 1.10.18、Maven 3.9.16、Eclipse Temurin 17.0.20.1) |
ant-props 是 Apache Ant 官方 AntLib 家族中负责属性展开增强的构件,唯一发布版本为 1.0.0,实时查询 Maven Central 确认(实测回显):
$ curl -s --max-time 30 https://repo1.maven.org/maven2/org/apache/ant/ant-props/maven-metadata.xml
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>org.apache.ant</groupId>
<artifactId>ant-props</artifactId>
<versioning>
<latest>1.0.0</latest>
<release>1.0.0</release>
<versions>
<version>1.0.0</version>
</versions>
<lastUpdated>20260627124331</lastUpdated>
</versioning>
</metadata>
结论:无需纠结版本,直接使用 1.0.0。运行时要求 Ant 1.8.0 及以上,JDK 8 与 17 均实测可用。安装步骤(JDK、Ant、Maven 的获取)见专栏安装指南,本文默认这些前置组件已就绪,直接从构件准备开始。
二、10 分钟最小可用(独立 Ant 路线)
本节从拿到 jar 到跑通第一个属性展开程序共 3 步:准备构件(1 分钟)→ 写构建文件(3 分钟)→ 运行验证(1 分钟,不含下载耗时)。
2.1 准备构件并校验
$ mkdir -p /opt/props-antlib /root/props-demo
$ cd /opt/props-antlib
$ curl -s --max-time 120 -O https://repo1.maven.org/maven2/org/apache/ant/ant-props/1.0.0/ant-props-1.0.0.jar
$ curl -s --max-time 60 -O https://repo1.maven.org/maven2/org/apache/ant/ant-props/1.0.0/ant-props-1.0.0.jar.sha1
$ ls -l ant-props-1.0.0.jar
-rw-r--r-- 1 root root 33260 Oct 15 05:58 ant-props-1.0.0.jar
$ echo "期望: $(cat ant-props-1.0.0.jar.sha1)"
期望: da89e11da0ab59ce1b1ea5e79a220f98a73c5792
$ echo "实测: $(sha1sum ant-props-1.0.0.jar | awk '{print $1}')"
实测: da89e11da0ab59ce1b1ea5e79a220f98a73c5792
期望与实测 SHA-1 一致,构件完整。把 jar 复制到工程目录,本文后续所有独立 Ant 示例都采用「jar 与构建文件同目录」的自包含布局:
$ cp /opt/props-antlib/ant-props-1.0.0.jar /root/props-demo/
$ ls /root/props-demo/
ant-props-1.0.0.jar
2.2 编写第一个构建文件
在 /root/props-demo 下创建 quickstart.xml,完整内容如下(直接照抄):
<?xml version="1.0" encoding="UTF-8"?>
<project name="props-quickstart" default="run" xmlns:props="antlib:org.apache.ant.props">
<typedef uri="antlib:org.apache.ant.props" resource="org/apache/ant/props/antlib.xml" classpath="ant-props-1.0.0.jar"/>
<propertyhelper>
<props:nested/>
<props:stringops/>
</propertyhelper>
<target name="run">
<property name="app.env" value="prod"/>
<property name="db.user.prod" value="app_rw"/>
<property name="db.pwd.prod" value="q1w2e3r4"/>
<property name="x" value="foo/bar/baz.ext"/>
<echo>[1] 嵌套展开 db.user = ${db.user.${app.env}}</echo>
<echo>[2] 嵌套展开 db.pwd = ${db.pwd.${app.env}}</echo>
<echo>[3] 未定义取默认 cache.max = ${cache.max:-512}</echo>
<property name="cache.max" value="1024"/>
<echo>[4] 已定义取原值 cache.max = ${cache.max:-512}</echo>
<echo>[5] 删前缀最短 ${x}#*/ = ${x#*/}</echo>
<echo>[6] 取扩展名 ${x}##*. = ${x##*.}</echo>
<echo>[7] 删扩展名 ${x}%.* = ${x%.*}</echo>
<property name="path.str" value="org/apache/ant/props"/>
<echo>[8] 全部替换斜杠为点 = ${path.str//\//.}</echo>
<echo>props-antlib quickstart OK</echo>
</target>
</project>
三个关键结构,缺一不可:
xmlns:props="antlib:org.apache.ant.props"声明在 project 上,让props:前缀有归属;<typedef uri="antlib:org.apache.ant.props" resource="org/apache/ant/props/antlib.xml" classpath="ant-props-1.0.0.jar"/>把 jar 里的组件按该命名空间装载进构建,uri 属性必须与 xmlns 指向一致;<propertyhelper>把两个属性委托器挂进 Ant 的属性求值链:props:nested提供嵌套展开(示例 [1][2][3]),props:stringops提供类 Shell 字符串运算(示例 [5] 到 [8])。
2.3 运行与逐条解读
$ cd /root/props-demo
$ export LANG=C.UTF-8
$ ANT_OPTS="-Xms256m -Xmx256m" ant -f quickstart.xml
Buildfile: /root/props-demo/quickstart.xml
run:
[echo] [1] 嵌套展开 db.user = app_rw
[echo] [2] 嵌套展开 db.pwd = q1w2e3r4
[echo] [3] 未定义取默认 cache.max = 512
[echo] [4] 已定义取原值 cache.max = 1024
[echo] [5] 删前缀最短 foo/bar/baz.ext#*/ = bar/baz.ext
[echo] [6] 取扩展名 foo/bar/baz.ext##*. = ext
[echo] [7] 删扩展名 foo/bar/baz.ext%.* = foo/bar/baz
[echo] [8] 全部替换斜杠为点 = org.apache.ant.props
[echo] props-antlib quickstart OK
BUILD SUCCESSFUL
Total time: 0 seconds
8 条用例全部按预期展开:
| 用例 | 语法 | 解读 |
|---|---|---|
| [1][2] | ${db.user.${app.env}} | 二级嵌套:先展开内层 app.env 得 prod,再取 db.user.prod;口令示例统一用 q1w2e3r4 |
| [3][4] | ${cache.max:-512} | 未定义时取默认 512,定义后取原值 1024 |
| [5] | ${x#*/} | 删最短前缀,foo/ 被去掉 |
| [6] | ${x##*.} | 删最长前缀,只剩扩展名 ext |
| [7] | ${x%.*} | 删最短后缀,.ext 被去掉 |
| [8] | ${path.str//\//.} | 全量替换,斜杠换成点 |
2.4 验证点清单
| 检查项 | 预期(实测值) | 不符时排查 |
|---|---|---|
| echo [1] | db.user = app_rw | 原样输出 ${db.user.${app.env}} → 5.1 节装载问题 |
| echo [3] | 512 | 报 propertyhelper doesn't support the nested "nested" element. → 5.1 节 |
| echo [8] | org.apache.ant.props | 仅 [1] 到 [4] 正常而 [5] 到 [8] 原样 → stringops 未挂载 |
| 构建结尾 | BUILD SUCCESSFUL | 中文变问号 → 5.3 节编码问题 |
三、Maven 集成路线(maven-antrun-plugin)
如果构建主链路是 Maven,ant-props 可以作为 maven-antrun-plugin 的插件依赖引入,由 antrun 内嵌的 Ant 运行时执行同样的展开逻辑,不向系统安装任何 jar。
3.1 创建工程与 pom.xml
$ mkdir -p /root/props-maven-demo
$ cd /root/props-maven-demo
$ vim pom.xml
pom.xml 完整内容(关键点:ant 与 ant-props 声明在 maven-antrun-plugin 的 <dependencies> 内进入插件类路径;xmlns:props 声明在 <target> 上):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>demo</groupId>
<artifactId>props-antlib-demo</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>17</maven.compiler.release>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.10.18</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-props</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.1.0</version>
<dependencies>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.10.18</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-props</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>props-quickstart</id>
<phase>validate</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target xmlns:props="antlib:org.apache.ant.props" name="props-quickstart">
<typedef resource="org/apache/ant/props/antlib.xml" classpathref="maven.plugin.classpath"/>
<propertyhelper>
<props:nested/>
<props:stringops/>
</propertyhelper>
<property name="app.env" value="prod"/>
<property name="db.user.prod" value="app_rw"/>
<property name="db.pwd.prod" value="q1w2e3r4"/>
<property name="x" value="foo/bar/baz.ext"/>
<echo>[1] 嵌套展开 db.user = ${db.user.${app.env}}</echo>
<echo>[2] 嵌套展开 db.pwd = ${db.pwd.${app.env}}</echo>
<echo>[3] 未定义取默认 cache.max = ${cache.max:-512}</echo>
<property name="cache.max" value="1024"/>
<echo>[4] 已定义取原值 cache.max = ${cache.max:-512}</echo>
<echo>[5] 删前缀最短 ${x}#*/ = ${x#*/}</echo>
<echo>[6] 取扩展名 ${x}##*. = ${x##*.}</echo>
<echo>[7] 删扩展名 ${x}%.* = ${x%.*}</echo>
<property name="path.str" value="org/apache/ant/props"/>
<echo>[8] 全部替换斜杠为点 = ${path.str//\//.}</echo>
<echo>props-antlib quickstart OK</echo>
</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
与独立 Ant 路线的差异只有两处:typedef 改用 classpathref="maven.plugin.classpath"(antrun 3.1.0 提供的内置引用,指向插件类路径);xmlns 声明放在 <target> 上而非 project 上。
3.2 构建验证
$ cd /root/props-maven-demo
$ export LANG=C.UTF-8
$ MAVEN_OPTS="-Xms256m -Xmx256m" mvn -B validate
实测回显(非首次运行;首次运行会额外下载 Maven 插件与依赖,实测耗时约 23 秒):
[INFO] -----------------------< demo:props-antlib-demo >-----------------------
[INFO] Building props-antlib-demo 1.0.0
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-antrun-plugin:3.1.0:run (props-quickstart) @ props-antlib-demo ---
[INFO] Executing tasks
[WARNING] [echo] [1] 嵌套展开 db.user = app_rw
[WARNING] [echo] [2] 嵌套展开 db.pwd = q1w2e3r4
[WARNING] [echo] [3] 未定义取默认 cache.max = 512
[WARNING] [echo] [4] 已定义取原值 cache.max = 1024
[WARNING] [echo] [5] 删前缀最短 foo/bar/baz.ext#*/ = bar/baz.ext
[WARNING] [echo] [6] 取扩展名 foo/bar/baz.ext##*. = ext
[WARNING] [echo] [7] 删扩展名 foo/bar/baz.ext%.* = foo/bar/baz
[WARNING] [echo] [8] 全部替换斜杠为点 = org.apache.ant.props
[WARNING] [echo] props-antlib quickstart OK
[INFO] Executed tasks
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.623 s
[INFO] Finished at: 2026-10-15T06:29:37Z
[INFO] ------------------------------------------------------------------------
8 条用例与独立 Ant 路线逐字一致。注意每条 echo 前缀是 [WARNING]:antrun 3.1.0 把 Ant 的标准输出路由到 Maven 的 WARN 级别日志,这是插件行为而非报错,以 BUILD SUCCESS 为准。
3.3 要点小结
- ant-props 必须声明为插件依赖而非工程依赖:委托器类要与 antrun 内嵌 Ant 运行时同一个类加载器可见,放工程依赖里时插件类路径看不到它,
<props:nested>会报装载失败。 <typedef classpathref="maven.plugin.classpath"/>无需 uri 时也可工作,但保持与独立路线相同的uri写法最稳妥。- Maven 侧不需要 LANG 之外的特殊配置,编码由 MAVEN_OPTS 与 locale 共同决定(见 5.3 节)。
四、四种装载方式实测对比
ant-props 的类要进入 Ant 的类加载器才能被 props: 前缀找到,共四种常用方式,本文逐一实测。除方式一外,其余都依赖 antlib 自动发现机制(仅凭 xmlns 声明即可定位 jar)。
4.1 方式一:同目录 typedef + classpath(本文主用)
jar 与构建文件同目录,构建文件内写全 uri 与 classpath 属性,2.3 节已实测通过。该方式不依赖任何系统状态,把 /root/props-demo 目录拷走即可在同类环境复用,工程自包含性最好。
4.2 方式二:ANT_HOME/lib 自动发现
Ubuntu apt 版 Ant 的 ANT_HOME 是 /usr/share/ant,把 jar 复制进其 lib 目录后,构建文件只需 xmlns 声明,不再需要 typedef:
$ cp /opt/props-antlib/ant-props-1.0.0.jar /usr/share/ant/lib/
$ cd /root/props-demo
$ export LANG=C.UTF-8
$ ant -f quickstart-nolib.xml
Buildfile: /root/props-demo/quickstart-nolib.xml
run:
[echo] [1] 嵌套展开 db.user = app_rw
[echo] [2] 未定义取默认 cache.ttl = 60
[echo] props-antlib nolib OK
BUILD SUCCESSFUL
Total time: 0 seconds
quickstart-nolib.xml 的 project 标签只声明了 xmlns:props="antlib:org.apache.ant.props",没有任何 typedef,实测自动发现生效。
4.3 方式三:ant -lib 参数
把 jar 移出 ANT_HOME/lib 后,用 -lib 显式指定 jar 所在目录,同样只靠 xmlns:
$ mv /usr/share/ant/lib/ant-props-1.0.0.jar /opt/props-antlib/
$ ant -lib /opt/props-antlib -f quickstart-nolib.xml
Buildfile: /root/props-demo/quickstart-nolib.xml
run:
[echo] [1] 嵌套展开 db.user = app_rw
[echo] [2] 未定义取默认 cache.ttl = 60
[echo] props-antlib nolib OK
BUILD SUCCESSFUL
Total time: 0 seconds
-lib 把目录加入 Ant 启动类路径,自动发现机制随即生效。适合无法改动 ANT_HOME/lib 但可控启动命令的场景。验证完把 jar 放回原位:
$ mv /opt/props-antlib/ant-props-1.0.0.jar /usr/share/ant/lib/
4.4 失败对照:两类真实报错
jar 完全不可见时(已移出 ANT_HOME/lib、无 typedef、无 -lib),实测构建失败:
BUILD FAILED
/root/props-demo/quickstart-nolib.xml:3: propertyhelper doesn't support the nested "nested" element.
同一构建文件在 CentOS 8 的 Ant 1.10.5 上即使加了 -lib 也失败(实测回显):
$ ant -lib /opt/props-antlib -f quickstart-nolib.xml
BUILD FAILED
/root/props-demo/quickstart-nolib.xml:3: propertyhelper doesn't support the nested "nested" element.
el8 发行版重打包的 Ant 1.10.5 丢失了 antlib 自动发现能力,此时只能用方式一。两类报错文本相同,排障时先确认 jar 可见性,再确认 Ant 来源是否支持自动发现(官方二进制包 1.10.18 实测支持,第六节有回显)。
4.5 选型小结
💡 技术拓展:四种装载方式各有取舍:
| 装载方式 | 构建文件要求 | 可移植性 | 本文实测结果 |
|---|---|---|---|
| 同目录 typedef + classpath | 需要 typedef 元素 | 高,拷走目录即可用 | 通过(2.3 节) |
| ANT_HOME/lib 自动发现 | 仅需 xmlns 声明 | 低,依赖系统目录状态 | 通过(4.2 节) |
| ant -lib 指定目录 | 仅需 xmlns 声明 | 中,依赖启动命令 | 通过(4.3 节);el8 上失败 |
| Maven antrun 插件类路径 | 需 antrun 配置 | 高,pom 即文档 | 通过(3.2 节) |
本文主用同目录 typedef + classpath:唯一在全部实测环境(Ubuntu 1.10.12、CentOS 8 1.10.5、官方 1.10.18)上都稳定成功的方式,且不污染系统状态;已全线接入 Maven 的团队选方式四。
五、常见坑与排障
以下三个坑在快速上手阶段出现频率最高,均为实测复现。
5.1 坑一:typedef 漏写 uri
现象:构建文件声明了 xmlns:props,typedef 却没写 uri 属性,运行时报:
BUILD FAILED
/root/props-demo/pitfall-nouri.xml:5: propertyhelper doesn't support the nested "nested" element.
定位:无 uri 的 typedef 把组件注册进默认命名空间,而 props:nested 按命名空间 antlib:org.apache.ant.props 查找,两边对不上。复现该报错的前提是 jar 不能被自动发现(本文把 jar 从 /usr/share/ant/lib 移出后实测);若 jar 同时在 ANT_HOME/lib 里,自动发现会掩盖这个坑,构建照常成功(实测确认)。修复:typedef 补上 uri="antlib:org.apache.ant.props",或干脆删除 typedef 改用自动发现。
5.2 坑二:propertyhelper 声明位置太靠后
属性值在定义那一刻就完成求值,propertyhelper 之前定义的属性不会经过新挂载的委托器。实测复现,pitfall.xml 内容:
<?xml version="1.0" encoding="UTF-8"?>
<project name="pit" default="all" xmlns:props="antlib:org.apache.ant.props">
<property name="early" value="${cache.ttl:-60}"/>
<propertyhelper>
<props:nested/>
<props:stringops/>
</propertyhelper>
<property name="late" value="${cache.ttl:-60}"/>
<target name="all">
<echo>[E1] helper 之前定义 early = ${early}</echo>
<echo>[E2] helper 之后定义 late = ${late}</echo>
</target>
</project>
运行回显:
$ cd /root/props-demo
$ export LANG=C.UTF-8
$ ant -f pitfall.xml
Buildfile: /root/props-demo/pitfall.xml
all:
[echo] [E1] helper 之前定义 early = ${cache.ttl:-60}
[echo] [E2] helper 之后定义 late = 60
BUILD SUCCESSFUL
Total time: 0 seconds
early 保留了字面量,late 正常取默认值 60。规则:propertyhelper 置于 project 顶部、所有 property 之前。
5.3 坑三:echo 中文显示问号
最小安装的 locale 缺省是 POSIX,JVM 默认字符集随之变为 ANSI_X3.4-1968,中文输出成问号(数字与英文不受影响)。修复:构建前导出 UTF-8 locale:
$ export LANG=C.UTF-8
本文所有运行命令都带该前导导出。持久化可写入 ~/.bashrc 或 /etc/profile.d/props-antlib.sh。
六、跨环境一致性验证
为确认快速入门结论不依赖单一环境,同一 quickstart.xml 与 pom.xml 在三套环境实测,结果一致:
| 环境 | 路线 | 实测结果 |
|---|---|---|
| Ubuntu 22.04,Ant 1.10.12,JDK 17.0.20.1 | 独立 Ant | 8 条用例全部按预期展开(2.3 节回显) |
| CentOS 8,Ant 1.10.5,JDK 17.0.1 | 独立 Ant | 8 条用例全部按预期展开,输出逐字一致 |
| Ubuntu 22.04,官方 Ant 1.10.18 二进制包,Maven 3.9.16,Eclipse Temurin 17.0.20.1 | 独立 Ant 与 Maven | 两种路线均通过,自动发现特性可用 |
官方 Ant 1.10.18 上的独立 Ant 回显(与 2.3 节一致,节选):
run:
[echo] [1] 嵌套展开 db.user = app_rw
[echo] [2] 嵌套展开 db.pwd = q1w2e3r4
[echo] props-antlib quickstart OK
BUILD SUCCESSFUL
Maven 3.9.16 上的构建回显(节选):
[INFO] --- antrun:3.1.0:run (props-quickstart) @ props-antlib-demo ---
[INFO] Executing tasks
[WARNING] [echo] [1] 嵌套展开 db.user = app_rw
[WARNING] [echo] props-antlib quickstart OK
[INFO] Executed tasks
[INFO] BUILD SUCCESS
[INFO] Total time: 0.688 s
[INFO] Finished at: 2026-10-15T06:38:58Z
唯一的环境差异在装载方式:CentOS 8 的 Ant 1.10.5 不支持自动发现,必须用方式一(4.4 节有失败回显);Ubuntu 与官方二进制包两种自动发现方式均可用。
七、运行参数
7.1 JVM 堆参数
Ant 与 Maven 分别通过环境变量 ANT_OPTS 与 MAVEN_OPTS 接收 JVM 参数,启动脚本(/usr/bin/ant 与 /usr/bin/mvn)在启动时读取并透传给 JVM。按 256 MB 配置:
$ export ANT_OPTS="-Xms256m -Xmx256m"
$ export MAVEN_OPTS="-Xms256m -Xmx256m"
参数位置与修改方法:临时修改用命令行前缀(如 2.3 节的写法),当前会话生效;当前用户持久化写入 ~/.bashrc;全系统持久化写入 /etc/profile.d/props-antlib.sh 后 source 或重新登录生效。ant-props 只做属性求值,内存占用极低,本文全部实测均在 256 MB 堆下完成,无内存压力。
7.2 locale 编码
$ export LANG=C.UTF-8
原因与现象见 5.3 节。两个变量可以合并写进同一条命令前缀:LANG=C.UTF-8 ANT_OPTS="-Xms256m -Xmx256m" ant -f quickstart.xml。
八、参考链接
- Apache Props Ant Library 主页:https://ant.apache.org/antlibs/props/index.html
- 官方手册(语法与用法):https://ant.apache.org/antlibs/props/manual/index.html
- Maven Central 构件:https://repo1.maven.org/maven2/org/apache/ant/ant-props/1.0.0/
- Ant 属性展开机制(Ant 手册 Properties 章节):https://ant.apache.org/manual/properties.html
- maven-antrun-plugin 手册:https://maven.apache.org/plugins/maven-antrun-plugin/