Apache Commons Collections 常用 CLI 命令与工具详解
commons-collections4 4.6.0 无自带 CLI,本文实测 jar/unzip/jdeps/javap 探查、java -cp 直跑与 Maven compile/dependency 命令。
Apache Commons Collections 常用 CLI 命令与工具详解
目标:Apache Commons Collections 本体是一个纯 Java 库,不发布任何自带 CLI 工具;与它相关的命令行操作全部发生在 JDK 工具链(jar/unzip/javap/jdeps/java)与 Maven 工具链(mvn)上。本篇把围绕 collections4 4.6.0 的常用命令一次讲全并逐条实测。已在 Ubuntu 22.04.5 LTS(x86_64、OpenJDK 17.0.20.1、Maven 3.9.16)实测通过。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- JDK:OpenJDK 17.0.20.1(jar/jdeps/javap/java 均来自 JDK 17)
- Maven:3.9.16(/opt/apache-maven-3.9.16)
- 目标库:commons-collections4-4.6.0.jar(官方 bin 包解压所得)
- 工作目录:/root/collections-lab
- jar 获取:https://downloads.apache.org/commons/collections/binaries/commons-collections4-4.6.0-bin.tar.gz
Commons Collections 在 Java 集合扩展库生态中的定位是「结构补齐包」,本身无守护进程、无配置文件,所有「运维」动作就是对 jar 的探查、校验与运行,下文按此展开。
💡 技术拓展:同样定位的集合扩展库在 CLI 层面几乎一致(都只是一个 jar + JDK 工具链)——
库 交付物 探查命令差异 Apache Commons Collections 单 jar(多版本 jar,含 module-info) jdeps 需 --multi-release Guava 单 jar(含 listenermanager 等多构件可选) 普通 jar,jdeps 可直接跑 Eclipse Collections 单 jar + 原始类型分离包 常见多 jar,-cp 需拼接 JDK 内置 java.util 随 JDK 分发 无需下载,jdeps --print-module-deps 常用于它 本文实测 commons-collections4 4.6.0:它是 multi-release jar(META-INF/versions/9/module-info.class,第五节实测),这一点直接影响 jdeps 命令写法。
二、准备 jar 与运行环境
本篇命令可独立执行,先取 jar 并校验(sha512 实测值 b54c6173 开头、d3aa5 结尾):
mkdir -p /root/collections-lab && cd /root/collections-lab
curl -sSOL https://downloads.apache.org/commons/collections/binaries/commons-collections4-4.6.0-bin.tar.gz
echo "b54c61737ff2ec7eaf6e1caf4d2adae42534dd28a9383c3fae1d5f299bce97b00ca15aee2c81ba4a4b50e64db69103cc3629a43af39b52f90990cdee944d3aa5 commons-collections4-4.6.0-bin.tar.gz" | sha512sum -c -
tar xzf commons-collections4-4.6.0-bin.tar.gz
实测回显:
commons-collections4-4.6.0-bin.tar.gz: OK
确认 JDK 与 jar 就位:
java -version
ls -lh commons-collections4-4.6.0/commons-collections4-4.6.0.jar
实测回显:
openjdk version "17.0.20.1" 2026-08-18
OpenJDK Runtime Environment (build 17.0.20.1+1-1-22.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 17.0.20.1+1-1-22.04-Ubuntu, mixed mode, sharing)
-rw-r--r-- 1 root root 913K Aug 6 09:54 commons-collections4-4.6.0/commons-collections4-4.6.0.jar
三、jar 内容探查(jar tf 与 unzip)
3.1 jar tf:列目录与统计
查看 jar 顶层结构:
jar tf commons-collections4-4.6.0/commons-collections4-4.6.0.jar | head -8
实测回显:
META-INF/
META-INF/MANIFEST.MF
org/
org/apache/
org/apache/commons/
org/apache/commons/collections4/
org/apache/commons/collections4/bag/
org/apache/commons/collections4/bidimap/
统计 class 文件总量,并确认某个目标类在包内:
jar tf commons-collections4-4.6.0/commons-collections4-4.6.0.jar | grep -c "\.class$"
jar tf commons-collections4-4.6.0/commons-collections4-4.6.0.jar | grep "trie/PatriciaTrie.class"
实测回显:
634
org/apache/commons/collections4/trie/PatriciaTrie.class
634 个 class 覆盖 bag/bidimap/map/multimap/multiset/trie 等约二十个子包;grep 命中 PatriciaTrie 说明前缀树能力在 jar 内。这一步是离线环境下确认「某个类到底有没有」的最快手段。
3.2 unzip:读 MANIFEST 元数据
版本、最低 JDK 与模块名都写在 MANIFEST 里:
unzip -p commons-collections4-4.6.0/commons-collections4-4.6.0.jar META-INF/MANIFEST.MF | head -12
实测回显:
Manifest-Version: 1.0
Created-By: Apache Maven Bundle Plugin 6.0.2
Java-Version: 8
Build-Jdk-Spec: 21
Specification-Title: Apache Commons Collections
Specification-Version: 4.6
Specification-Vendor: The Apache Software Foundation
Implementation-Title: Apache Commons Collections
Implementation-Version: 4.6.0
Implementation-Vendor: The Apache Software Foundation
Automatic-Module-Name: org.apache.commons.collections4
逐项解读:Implementation-Version=4.6.0 可用于运行时核对实际加载的版本;Java-Version: 8 印证官方「Java 8 or later」要求;Build-Jdk-Spec: 21 说明发行物用 JDK 21 构建,但不影响在 8+ 运行;Automatic-Module-Name 声明了 JPMS 模块名,模块化工程 import 该 jar 时用它。
四、javap:查看类签名
不打开 IDE 就能看类的公开方法与构造器,排查「有没有这个方法、参数长什么样」:
javap -cp commons-collections4-4.6.0/commons-collections4-4.6.0.jar org.apache.commons.collections4.MapUtils | head -12
实测输出节选(实测首尾):
Compiled from "MapUtils.java"
public class org.apache.commons.collections4.MapUtils {
public static final java.util.SortedMap EMPTY_SORTED_MAP;
public static void debugPrint(java.io.PrintStream, java.lang.Object, java.util.Map<?, ?>);
public static <K, V> java.util.Map<K, V> emptyIfNull(java.util.Map<K, V>);
public static <K, V> org.apache.commons.collections4.IterableMap<K, V> fixedSizeMap(java.util.Map<K, V>);
public static <K> java.lang.Boolean getBoolean(java.util.Map<? super K, ?>, K);
再对比两个多值 Map 实现的容量参数(grep 过滤构造器行):
javap -cp commons-collections4-4.6.0/commons-collections4-4.6.0.jar org.apache.commons.collections4.multimap.ArrayListValuedHashMap | grep ArrayListValuedHashMap
实测回显:
public org.apache.commons.collections4.multimap.ArrayListValuedHashMap()
public org.apache.commons.collections4.multimap.ArrayListValuedHashMap(int)
public org.apache.commons.collections4.multimap.ArrayListValuedHashMap(int, int)
public org.apache.commons.collections4.multimap.ArrayListValuedHashMap(java.util.Map<? extends K, ? extends V>)
public org.apache.commons.collections4.multimap.ArrayListValuedHashMap(org.apache.commons.collections4.MultiValuedMap<? extends K, ? extends V>)
javap 直接给出编译期签名,写代码前用它核对方法存在性,比报错后再查省一个来回。
五、jdeps:依赖分析
jdeps 分析 jar 的 JDK 模块依赖,4.6.0 上直接跑会报错——这是实测踩到的第一个坑:
jdeps commons-collections4-4.6.0/commons-collections4-4.6.0.jar
实测回显:
Error: commons-collections4-4.6.0.jar is a multi-release jar file but --multi-release option is not set
原因:该 jar 是 multi-release jar(内含 META-INF/versions/9/module-info.class)。加 --multi-release 17 重新执行:
jdeps --multi-release 17 commons-collections4-4.6.0/commons-collections4-4.6.0.jar | head -8
实测输出节选(实测首尾):
org.apache.commons.collections4
[file:///root/collections-lab/commons-collections4-4.6.0/commons-collections4-4.6.0.jar]
requires mandated java.base
requires java.xml
org.apache.commons.collections4 -> java.base
org.apache.commons.collections4 -> java.xml
org.apache.commons.collections4 -> java.io java.base
org.apache.commons.collections4 -> java.lang java.base
结论解读:整个库只 requires java.base 与 java.xml 两个 JDK 模块,除自身外零第三方依赖——这与「单 jar 零传递依赖」的官方口径一致(java.xml 来自个别类对 org.w3c.dom 的引用,jdeps 输出可逐包追溯)。做基线审计或精简运行时镜像时,这条命令的输出就是依赖白名单依据。
六、Maven 工具链命令
6.1 mvn -version 与 compile
确认工具链身份:
mvn -version
实测回显:
Apache Maven 3.9.16 (2bdd9fddda4b155ebf8000e807eb73fd829a51d5)
Maven home: /opt/apache-maven-3.9.16
Java version: 17.0.20.1, vendor: Ubuntu, runtime: /usr/lib/jvm/java-17-openjdk-amd64
在依赖了 collections4 4.6.0 的工程(pom 写法见《Ubuntu 22.04 安装 Apache Commons Collections 指南》5.1,坐标 org.apache.commons:commons-collections4:4.6.0)里编译:
mvn compile
实测输出节选(实测首尾):
[INFO] Building collections-demo 1.0.0
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] BUILD SUCCESS
[INFO] Total time: 0.683 s
[INFO] Finished at: 2026-10-13T04:59:43Z
6.2 dependency 命令组
把依赖 jar 物理复制到指定目录(方案B式直接引用时常用):
mvn dependency:copy-dependencies -DoutputDirectory=target/dep
ls target/dep/
实测回显:
commons-collections4-4.6.0.jar
列出依赖树中的目标库及其 scope、模块名:
mvn dependency:list | grep collections4
实测回显:
[INFO] org.apache.commons:commons-collections4:jar:4.6.0:compile -- module org.apache.commons.collections4
copy-dependencies 适合把库 jar 连同产物一起交付;dependency:list 用于核对 scope 与实际解析版本(排查「明明写了 4.6.0 却被管理成别的版本」类问题)。
七、java -cp 组合运行与批量验证
不打包 fat jar,直接 -cp 拼当前目录与库 jar 运行单类。先写并编译验证程序:
cd /root/collections-lab
cat > HelloCollections.java << "EOF"
import org.apache.commons.collections4.Bag;
import org.apache.commons.collections4.bag.HashBag;
public class HelloCollections {
public static void main(String[] args) {
Bag<String> bag = new HashBag<>();
bag.add("apple", 3);
bag.add("banana");
System.out.println("Hello commons-collections4! bag = " + bag);
}
}
EOF
javac -nowarn -cp commons-collections4-4.6.0/commons-collections4-4.6.0.jar HelloCollections.java
java -cp .:commons-collections4-4.6.0/commons-collections4-4.6.0.jar HelloCollections
实测回显:
Hello commons-collections4! bag = [1:banana,3:apple]
示例较多时用 for 循环批量跑(示例源码为七个独立类,-cp 同上):
for f in BagDemo BidiMapDemo MapIteratorDemo PredicateTransformerDemo MultiValuedMapDemo SetOpsDemo TrieDemo; do echo "===RUN $f==="; java -cp .:commons-collections4-4.6.0/commons-collections4-4.6.0.jar $f; done
实测输出节选(实测首尾):
===RUN BagDemo===
bag = [1:banana,4:apple]
getCount(apple) = 4
===RUN BidiMapDemo===
map = {alice=1001, bob=1002, carol=1003}
inverse = {1001=alice, 1002=bob, 1003=carol}
===RUN TrieDemo===
prefixMap(col) = {collection=1, collections=2, collector=3}
prefixMap(bi) = {bicycle=4}
firstKey = bicycle, lastKey = collector
⚠️ 注意:批量脚本里 javac 若报「unmappable character (0xE5) for encoding US-ASCII」,是无 LANG 环境下 javac 默认编码导致,给 javac 加 -encoding UTF-8 即可(实测命中过);java 运行期不受影响。
八、参考链接
- JDK jar 工具手册:https://docs.oracle.com/en/java/javase/17/docs/specs/man/jar.html
- JDK jdeps 工具手册(--multi-release 说明):https://docs.oracle.com/en/java/javase/17/docs/specs/man/jdeps.html
- JDK javap 工具手册:https://docs.oracle.com/en/java/javase/17/docs/specs/man/javap.html
- Apache Maven CLI 参考:https://maven.apache.org/guides/introduction/introduction-to-the-pom.html
- 官方发行包目录(本篇 jar 来源):https://downloads.apache.org/commons/collections/