Apache Ivy 2.6.0 常用 CLI 命令与工具详解

详解 Apache Ivy 2.6.0 独立 CLI(java -jar)与 Ant 任务两种用法:-dependency/-retrieve 实测、选项速查表、resolve/retrieve/report 任务、依赖报告产物与 CI 缓存实践,含 10 个实测 FAQ

Apache IvyIvyApache运维2026/10/14

Apache Ivy 2.6.0 常用 CLI 命令与工具详解

Ivy 有两种"命令行"形态:独立 CLI(java -jar ivy-2.6.0.jar,无需 Ant)与 Ant 任务(ant resolve 等)。本文标注"实测"的输出均为 Ubuntu 22.04 + OpenJDK 17 容器内真实回显;标注"参考"的选项来自随包官方文档。

一、独立 CLI 快速上手

java -jar /opt/apache-ivy-2.6.0/ivy-2.6.0.jar [选项] [模式参数]

无 Ant 环境(CI 容器、临时排障)首选此形态。运行后 Ivy 使用 jar 内置默认 settings(日志首行可确认):

:: loading settings :: url = jar:file:/opt/apache-ivy-2.6.0/ivy-2.6.0.jar!/org/apache/ivy/core/settings/ivysettings.xml

二、全局选项速查表(参考,均经 2.6.0 主流程验证)

选项说明
-dependency org name rev临时依赖模式:不写 ivy.xml 直接解析指定模块
-ivy ivy.xml指定模块描述符(默认当前目录 ivy.xml)
-settings ivysettings.xml指定引擎设置文件
-conf 配置文件指定 settings(与 -settings 等价的旧写法,注意区分下文的 -confs)
-cache 目录覆盖缓存目录
-confs conf1,conf2只解析这些 configuration(默认 default)
-retrieve pattern把解析结果按 pattern 复制到本地(不写只进缓存)
-cachepath 文件把缓存 classpath 写入文本文件
-revision rev覆盖模块 revision
-main 类名 [参数]解析后直接运行主类(把依赖喂给 java)
-notransitive关闭传递依赖
-syncretrieve 时同步删除多余文件
-m2compatible兼容 Maven 2 仓库布局
-nosplash不输出版本横幅

三、-dependency 模式实测

场景:不建工程,快速拿到某个库(并验证它有哪些传递依赖)。

cd /tmp && java -jar /opt/apache-ivy-2.6.0/ivy-2.6.0.jar -dependency commons-lang commons-lang 2.6

真实回显(节选):

:: resolving dependencies :: commons-lang#commons-lang-caller;working
        confs: [default]
        found commons-lang#commons-lang;2.6 in public
        found junit#junit;3.8.1 in public
downloading https://repo1.maven.org/maven2/commons-lang/commons-lang/2.6/commons-lang-2.6-javadoc.jar ...
.................................................................................................................................. (1585kB)
.. (0kB)
        [SUCCESSFUL ] commons-lang#commons-lang;2.6!commons-lang.jar(javadoc) (10295ms)
downloading https://repo1.maven.org/maven2/commons-lang/commons-lang/2.6/commons-lang-2.6-sources.jar ...
......................... (364kB)
.. (0kB)
        [SUCCESSFUL ] commons-lang#commons-lang;2.6!commons-lang.jar(source) (2781ms)
downloading https://repo1.maven.org/maven2/commons-lang/commons-lang/2.6/commons-lang-2.6.jar ...
..................... (277kB)
.. (0kB)
        [SUCCESSFUL ] commons-lang#commons-lang;2.6!commons-lang.jar (3241ms)
downloading https://repo1.maven.org/maven2/junit/junit/3.8.1/junit-3.8.1.jar ...
......... (118kB)
.. (0kB)
        [SUCCESSFUL ] junit#junit;3.8.1!junit.jar (2126ms)
:: resolution report :: resolve 9704ms :: artifacts dl 18449ms
        ---------------------------------------------------------------------
        |                  |            modules            ||   artifacts   |
        |       conf       | number| search|dwnlded|evicted|| number|dwnlded|
        ---------------------------------------------------------------------
        |      default     |   2   |   2   |   2   |   0   ||   4   |   4   |
        ---------------------------------------------------------------------

要点:

  1. 传递依赖自动带入(commons-lang 2.6 → junit 3.8.1);
  2. Maven 仓库的 javadoc/sources 分类件默认也下载(4 artifacts);只要二进制时加 -notransitive 且 conf 映射收紧可减少下载;
  3. 结果只进缓存 /root/.ivy2/cache,不落当前目录。

四、-retrieve 落盘实战(含一次真实报错)

4.1 错误写法与报错原文

java -jar /opt/apache-ivy-2.6.0/ivy-2.6.0.jar -dependency commons-lang commons-lang 2.6 -retrieve 'cli/[artifact].[ext]'
        at org.apache.ivy.Ivy.retrieve(Ivy.java:561)
        at org.apache.ivy.Main.run(Main.java:389)
        at org.apache.ivy.Main.run(Main.java:284)
        at org.apache.ivy.Main.main(Main.java:233)
Caused by: java.lang.RuntimeException: Multiple artifacts of the module commons-lang#commons-lang;2.6 are retrieved to the same file! Update the retrieve pattern to fix this error.
        at org.apache.ivy.core.retrieve.RetrieveEngine.determineArtifactsToCopy(RetrieveEngine.java:426)
        at org.apache.ivy.core.retrieve.RetrieveEngine.retrieve(RetrieveEngine.java:122)
        ... 4 more

根因:缓存中同模块有 jar/javadoc/source 三类 artifact,pattern 缺 [type] 维度导致文件名冲突。

4.2 修正后成功

java -jar /opt/apache-ivy-2.6.0/ivy-2.6.0.jar -dependency commons-lang commons-lang 2.6 -retrieve 'cli/[artifact]-[type].[ext]'
ls -l cli/
:: retrieving :: commons-lang#commons-lang-caller
        confs: [default]
        4 artifacts copied, 0 already retrieved (2346kB/16ms)
=== cli 目录 ===
-rw-r--r-- 1 root root  284220 Jan 16  2011 commons-lang-jar.jar
-rw-r--r-- 1 root root 1624033 Jan 16  2011 commons-lang-javadoc.jar
-rw-r--r-- 1 root root  372982 Jan 16  2011 commons-lang-source.jar
-rw-r--r-- 1 root root  121070 Aug  1  2005 junit-jar.jar

五、-ivy 模式与 -cachepath(CI 常用组合,参考用法)

# 用现有 ivy.xml 解析并生成 classpath 文件
java -jar ivy-2.6.0.jar -ivy ivy.xml -cachepath cp.txt
javac -cp "$(cat cp.txt)" -d build/classes src/...

-cachepath 输出的是缓存中各 jar 的绝对路径拼串,配合 javac/java 可完全绕开手工拷贝 lib。生产 CI 亦可用 -main 一步到位:java -jar ivy.jar -ivy ivy.xml -main com.example.Main arg1(Ivy 解析后直接以该 classpath 启动主类)。

六、Ant 任务形态(build.xml 编排)

工程根 build.xml 关键段(实测工程全文见安装指南篇第七章):

<project xmlns:ivy="antlib:org.apache.ivy.ant">
    <target name="resolve"><ivy:resolve/></target>
    <target name="retrieve" depends="resolve"><ivy:retrieve pattern="lib/[artifact].[ext]"/></target>
    <target name="report" depends="resolve"><ivy:report todir="report"/></target>
</project>

6.1 ant resolve 首跑实测

[ivy:resolve] :: Apache Ivy 2.6.0 - 20260712075753 :: https://ant.apache.org/ivy/ ::
[ivy:resolve] :: resolving dependencies :: com.example#ivy-demo;1.0
[ivy:resolve]   confs: [default]
[ivy:resolve]   found org.apache.commons#commons-lang3;3.21.0 in public
[ivy:resolve]   [3.21.0] org.apache.commons#commons-lang3;3.+
[ivy:resolve] downloading https://repo1.maven.org/maven2/org/apache/commons/commons-lang3/3.21.0/commons-lang3-3.21.0.jar ...
[ivy:resolve]   [SUCCESSFUL ] org.apache.commons#commons-lang3;3.21.0!commons-lang3.jar (7138ms)
[ivy:resolve] :: resolution report :: resolve 15281ms :: artifacts dl 7142ms
        |      default     |   1   |   1   |   1   |   0   ||   1   |   1   |

BUILD SUCCESSFUL
Total time: 23 seconds

6.2 二次 resolve 缓存命中

[ivy:resolve] :: resolution report :: resolve 3351ms :: artifacts dl 1ms
        |      default     |   1   |   0   |   0   |   0   ||   1   |   0   |

retrieve:
[ivy:retrieve]  1 artifacts copied, 0 already retrieved (731kB/5ms)

dwnlded=0 即缓存命中;网络抖动不再影响重复构建。

6.3 ant report 产物

[ivy:report] Processing /root/.ivy2/cache/com.example-ivy-demo-default.xml to /root/ivy-demo/report/com.example-ivy-demo-default.html
[ivy:report] Processing /root/.ivy2/cache/com.example-ivy-demo-default.xml to /root/ivy-demo/report/com.example-ivy-demo-default.graphml

BUILD SUCCESSFUL
Total time: 3 seconds
=== report 目录 ===
-rw-r--r-- 1 root root 1917 Oct 14 15:10 com.example-ivy-demo-default.graphml
-rw-r--r-- 1 root root 6322 Oct 14 15:10 com.example-ivy-demo-default.html
-rw-r--r-- 1 root root 4680 Oct 14 15:10 ivy-report.css

HTML 页标题(实测):Ivy report :: ivy-demo by com.example :: default,依赖树、版本、大小一目了然;.graphml 可导入 yEd/Gephi 画依赖图。报告输入是缓存里的解析 XML,所以必须先 resolve。

七、与 Maven 的工具对照

需求IvyMaven
只下依赖不编译java -jar ivy.jar -dependency org name revmvn dependency:go-offline
生成 classpath 文件-cachepath cp.txtmvn dependency:build-classpath -Dmdep.outputFile=cp.txt
依赖报告ant report(HTML+graphml)mvn dependency:tree(文本)
描述符ivy.xml(自由 conf 模型)pom.xml(固定 scope 模型)

八、CI 实践与缓存复用

  1. 缓存复用:把 ~/.ivy2/cache 挂 CI 缓存卷,二次构建 dwnlded=0(实测秒级);
  2. 可重现:CI 中固定 -settings 指向版本化管理的 ivysettings.xml,避免默认链漂移;
  3. 隔离:多任务并行时用 -cache /ci/cache/job-${BUILD_ID} 或开启 settings 的锁策略,防止并发写缓存冲突;
  4. 报表归档:ant report 的 HTML 作为构建产物归档,审依赖升级。

九、FAQ(实测排障)

Q1:CLI 运行报 java.lang.NoClassDefFoundError? 用 bin 极简包缺依赖;换 bin-with-deps 包(实测 with-deps 的 jar 可独立运行全部功能)。

Q2:-retrieve 报 Multiple artifacts ... same file? pattern 缺类型维度,改 cli/[artifact]-[type].[ext](第四章实测)。

Q3:只想下二进制 jar,别下 javadoc/source? Maven 仓库里这些是独立分类件。用 -confs default 且依赖映射只到 master,或直接 -retrieve 后删多余类型;也可换用 default->default(master) 映射的 ivy.xml 走 -ivy 模式。

Q4:解析到的版本和预期不同? 3.+/区间等动态版本以解析时刻仓库最新为准(实测 3.21.0);固定需求写精确 rev。

Q5:怎么查看某依赖的传递树? ant report 的 HTML 或 -dependency 模式的 resolution 表格(modules 列)。

Q6:CLI 模式能 publish 吗? 独立 CLI 面向解析/检索;发布走 ivy:publish(Ant 任务)或 CI 脚本化 deliver。

Q7:代理环境怎么配? JAVA_OPTS/ANT_OPTS 加 -Dhttps.proxyHost=... -Dhttps.proxyPort=...,Ivy 走 JDK 网络栈。

Q8:如何强制重新校验缓存? ant resolve -Doverwrite=true 或清对应模块缓存目录;changing="true" 的依赖每次自动核对。

Q9:-main 启动的主类找不到? 确认 -ivy 描述符里该类所属构件在 default conf 中;classpath 由缓存直接拼出,主类需在依赖或本工程 classes 里。

Q10:Windows 下路径分隔符? retrieve pattern 用 /(Ivy 统一转义),classpath 拼接用平台分隔符(-cachepath 已自动处理)。

参考链接

  • Ivy Main(CLI)官方文档:随包 /opt/apache-ivy-2.6.0/doc/standalone.html
  • Ant 任务参考:随包 /opt/apache-ivy-2.6.0/doc/ant.html
  • Ivy 官网:https://ant.apache.org/ivy/