Ubuntu 22.04 安装 Apache Commons Collections 指南

在 Ubuntu 22.04 从零安装 Apache Commons Collections 4.6.0:Maven 依赖与手动 bin 包两种方案、JDK 多版本管理、最小验证程序与卸载清理,全程命令实测。

Apache Commons CollectionsApache Commons Collections2026/10/13

Ubuntu 22.04 安装 Apache Commons Collections 指南

目标:在 Ubuntu 22.04 上从零搭建一个能编译、能运行 Apache Commons Collections(commons-collections4)4.6.0 的 Java 环境,覆盖 JDK/Maven 安装、Maven 依赖与手动下载 bin 包两种接入方案、JDK 多版本管理与卸载清理。已在 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(软件包 openjdk-17-jdk-headless,另演示安装 openjdk-11-jdk-headless)
  • 构建工具:Apache Maven 3.9.16(tarball 安装于 /opt/apache-maven-3.9.16)
  • 目标库:Apache Commons Collections 4.6.0(Maven 坐标 org.apache.commons:commons-collections4)
  • 工作目录:/root/collections-lab
  • 依赖网络:downloads.apache.org、dlcdn.apache.org、repo.maven.apache.org 直连可达

二、版本选型与前置要求

安装前先确定两件事:选哪个版本的 Commons Collections,以及准备什么版本的 JDK。Commons Collections 是 JDK 内置集合框架之外的集合扩展库,为 Java 补充了 Bag(计数集合)、BidiMap(双向映射)、MultiValuedMap(一键多值)、Trie(前缀树)等 JDK 没有的数据结构。

💡 技术拓展:Java 集合扩展库不止本文选用的 Apache Commons Collections,主流选项对比——

库定位/特点适用场景
JDK 内置 java.util官方标准集合,List/Set/Map 稳定通用绝大多数普通业务
Apache Commons Collections补充 Bag/BidiMap/MultiValuedMap/Trie/谓词装饰器等结构需要 JDK 缺失的集合结构与函数式工具
GuavaGoogle 工具集,Multiset/Multimap/Range/Table 与不可变集合已引入 Guava 生态的项目
Eclipse Collections高性能、内存优化,含原始类型(int/long)专用集合大数据量、性能与内存敏感

本文选用 Apache Commons Collections 4.6.0:单 jar 零传递依赖、结构类型最全,且实测官方下载与 Maven 中央仓库均可直接获取。

2.1 版本选型表

以官方发布目录(downloads.apache.org/commons/collections/)为准,2026 年 10 月时 4.x 最新版为 4.6.0:

版本发布日期包名最低 JDK状态说明
3.2.22015-11-14org.apache.commons.collectionsJava 5+3.x 最终版,已 EOL,存在反序列化漏洞历史(见 FAQ)
4.42019-07-09org.apache.commons.collections4Java 8+4.x 稳定老版本,存量项目常见
4.5.02025-04-22org.apache.commons.collections4Java 8+4.x 过渡版本
4.6.02026-08-10org.apache.commons.collections4Java 8+当前官方最新,本篇实测版本

关键差异:3.x 与 4.x 不能混用——3.x 的包名是 org.apache.commons.collections,4.x 改为 org.apache.commons.collections4,类与方法的泛型签名也有大量变化;新项目一律选 4.6.0,老项目若仍在 3.x 应尽快迁移(3.x 已停止维护且有著名的反序列化漏洞利用史)。4.6.0 官方 RELEASE-NOTES 明确写着「Java 8 or later is required」,因此 JDK 8/11/17/21 均可运行,本篇以 17 为主线并在第六节演示 11/17 共存。

2.2 前置要求

  • JDK 8 及以上(本篇安装 17,另演示 11);编译与运行都需要 JDK 而非仅 JRE。
  • root 或 sudo 权限:apt 安装软件包、写 /opt 与 /usr/local/bin。
  • 网络可达 downloads.apache.org(官方发行包)与 repo.maven.apache.org(Maven 中央仓库)。

三、安装 JDK 17

JDK 是编译和运行 commons-collections4 程序的基础。先更新软件源索引,再安装 openjdk-17-jdk-headless 软件包:

sudo apt-get update
sudo apt-get install -y openjdk-17-jdk-headless

实测输出节选(本环境已装 17,重装命令会确认包状态,全新机器会执行下载安装):

Hit:2 http://security.ubuntu.com/ubuntu jammy-security InRelease
Hit:3 http://archive.ubuntu.com/ubuntu jammy-updates InRelease
openjdk-17-jdk-headless is already the newest version (17.0.20.1+1-1~22.04).
openjdk-17-jdk-headless set to manually installed.
0 upgraded, 0 newly installed, 0 to remove and 1 not upgraded.

验证 JDK 已就位(编译器 javac 必须同时存在,否则第五节无法编译示例):

java -version
javac -version

实测回显:

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)
javac 17.0.20.1

四、安装 Maven 3.9.16

方案A(Maven 依赖接入)需要一个可用的 Maven。Ubuntu 源里的 maven 包版本偏旧,这里采用官方 tarball 安装到 /opt,再做软链接进 PATH。先下载 3.9.16 并做 sha512 校验(校验值取自官方 .sha512 文件,实测内容为 831a8591 开头、b6f6 结尾,注意官方该文件只有散列值没有文件名,需自行拼接校验行):

mkdir -p /tmp/maven-demo && cd /tmp/maven-demo
curl -sSOL https://dlcdn.apache.org/maven/maven-3/3.9.16/binaries/apache-maven-3.9.16-bin.tar.gz
curl -sSO https://dlcdn.apache.org/maven/maven-3/3.9.16/binaries/apache-maven-3.9.16-bin.tar.gz.sha512
cat apache-maven-3.9.16-bin.tar.gz.sha512
echo "$(cat apache-maven-3.9.16-bin.tar.gz.sha512)  apache-maven-3.9.16-bin.tar.gz" | sha512sum -c -

实测回显:

831a8591fe20c8243b1dbe7d71e3244f31d1665b0804b2e825e38cbbe5ce0cafb8338851f90780735568773e0a6cd07bbec107cda0b896b008b861075358b6f6
apache-maven-3.9.16-bin.tar.gz: OK

校验通过后解压到 /opt,并把 mvn 软链到 /usr/local/bin 使其在 PATH 中生效:

sudo tar xzf apache-maven-3.9.16-bin.tar.gz -C /opt
sudo ln -s /opt/apache-maven-3.9.16/bin/mvn /usr/local/bin/mvn
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

验证要点:mvn -version 输出的 Maven home 指向 /opt/apache-maven-3.9.16、Java version 为 17.0.20.1,即说明软链与 JDK 识别都生效。Maven 依赖的本地仓库默认在 ~/.m2/repository,后续下载的 jar 都落在这里。

五、获取 commons-collections4 的两种方案

Commons Collections 本体只是一个 jar,接入项目有两种主流方式:方案A通过 Maven 声明依赖自动下载;方案B手动下载官方 bin 包,用 javac/java -cp 直跑。两种方案下面都给出从建目录到跑通验证程序的完整命令。

5.1 方案A:Maven 依赖接入(推荐)

先创建最小 Maven 工程:目录结构为 pom.xml 加 src/main/java 源码目录。

mkdir -p /root/collections-lab/maven-demo/src/main/java/com/example
cd /root/collections-lab/maven-demo

写入 pom.xml,核心是 dependencies 里的 commons-collections4 4.6.0 坐标:

<?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>com.example</groupId>
    <artifactId>collections-demo</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.6.0</version>
        </dependency>
    </dependencies>
</project>

配置说明:groupId/artifactId/version 是本项目自身坐标;maven.compiler.source/target 设为 8 表示按 Java 8 字节码编译,与 commons-collections4 的最低要求对齐,可保证产物在 JDK 8+ 全兼容;project.build.sourceEncoding 固定 UTF-8,避免中文源码乱码;dependency 部分即目标库,scope 缺省为 compile。

写入最小验证程序 src/main/java/com/example/CollectionDemo.java,用 HashBag 做计数:

package com.example;

import org.apache.commons.collections4.Bag;
import org.apache.commons.collections4.bag.HashBag;

public class CollectionDemo {
    public static void main(String[] args) {
        Bag<String> bag = new HashBag<>();
        bag.add("apple", 3);
        bag.add("banana");
        System.out.println("collections4 works! bag = " + bag);
        System.out.println("getCount(apple) = " + bag.getCount("apple"));
    }
}

编译(首次执行会从中央仓库下载依赖与插件,网络慢时多等片刻):

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

把依赖 jar 复制到 target/dep,再用 java -cp 运行验证程序:

mvn dependency:copy-dependencies -DoutputDirectory=target/dep
ls target/dep/
java -cp target/classes:target/dep/\* com.example.CollectionDemo

实测回显:

commons-collections4-4.6.0.jar
collections4 works! bag = [1:banana,3:apple]
getCount(apple) = 3

输出里的 [1:banana,3:apple] 是 HashBag 的格式:元素:计数。看到这两行即说明依赖、编译、运行全链路打通。

5.2 方案B:手动下载 bin 包 + javac/java -cp 直跑

不使用 Maven 时,直接取官方 bin 包。下载 4.6.0 并用官方 sha512 校验(校验值 b54c61737ff2ec7eaf6e1caf4d2adae42534dd28a9383c3fae1d5f299bce97b00ca15aee2c81ba4a4b50e64db69103cc3629a43af39b52f90990cdee944d3aa5,实测来自 downloads.apache.org 的 .sha512 文件):

mkdir -p /root/collections-lab/manual && cd /root/collections-lab/manual
curl -sSOL https://downloads.apache.org/commons/collections/binaries/commons-collections4-4.6.0-bin.tar.gz
ls -lh commons-collections4-4.6.0-bin.tar.gz
echo "b54c61737ff2ec7eaf6e1caf4d2adae42534dd28a9383c3fae1d5f299bce97b00ca15aee2c81ba4a4b50e64db69103cc3629a43af39b52f90990cdee944d3aa5  commons-collections4-4.6.0-bin.tar.gz" | sha512sum -c -

实测回显:

-rw-r--r-- 1 root root 12M Oct 13 05:00 commons-collections4-4.6.0-bin.tar.gz
commons-collections4-4.6.0-bin.tar.gz: OK

解压并确认 jar 位置:

tar xzf commons-collections4-4.6.0-bin.tar.gz
ls commons-collections4-4.6.0/

实测回显:

LICENSE.txt
NOTICE.txt
RELEASE-NOTES.txt
apidocs
commons-collections4-4.6.0-javadoc.jar
commons-collections4-4.6.0-sources.jar
commons-collections4-4.6.0-test-sources.jar
commons-collections4-4.6.0-tests.jar
commons-collections4-4.6.0.jar

bin 包除主 jar 外还带 javadoc/sources 两个 jar 与离线 apidocs 目录,主 jar 即 commons-collections4-4.6.0.jar。写验证程序 HelloCollections.java:

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);
    }
}

编译并运行(-cp 同时指定当前目录与目标 jar):

javac -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

实测回显(javac 有一条 Bag 已标记过时的提醒,含义见 FAQ Q2,不影响运行):

Note: HelloCollections.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Hello commons-collections4! bag = [1:banana,3:apple]

5.3 方案对比与选型建议

维度方案A:Maven 依赖方案B:手动 bin 包
获取方式pom 声明坐标,mvn 自动下载curl 下载 bin tar.gz,sha512 校验
版本升级改 pom 中 version 一处重新下载解压并改 -cp
传递依赖自动管理(本库无传递依赖)手动处理
适用场景常规工程、持续集成无 Maven 的机器、快速验证、离线环境
依赖 jar 位置~/.m2/repository 与 target/dep任意自选目录

关键差异:本库是零传递依赖的单 jar,方案B的 -cp 维护成本接近于零,非常适合脚本与教学;但凡项目规模成长到需要统一构建,选方案A,版本管理与仓库缓存都由 Maven 托管。本篇后续章节两种环境均保留可用。

六、JDK 多版本管理(11 与 17 共存)

commons-collections4 4.6.0 只要求 Java 8+,实际生产常出现「新项目 17、老项目 11」并存。Ubuntu 用 update-alternatives 管理多 JDK,先安装 openjdk-11-jdk-headless:

sudo apt-get install -y openjdk-11-jdk-headless

实测输出节选(实测首尾,dpkg 安装阶段后即完成 update-alternatives 登记):

update-alternatives: using /usr/lib/jvm/java-11-openjdk-amd64/bin/jjs to provide /usr/bin/jjs (jjs) in auto mode
update-alternatives: using /usr/lib/jvm/java-11-openjdk-amd64/bin/rmic to provide /usr/bin/rmic (rmic) in auto mode

查看系统已登记的 java 候选路径:

update-alternatives --list java
ls /usr/lib/jvm/

实测回显:

/usr/lib/jvm/java-11-openjdk-amd64/bin/java
/usr/lib/jvm/java-17-openjdk-amd64/bin/java
java-1.11.0-openjdk-amd64
java-1.17.0-openjdk-amd64
java-11-openjdk-amd64
java-17-openjdk-amd64

切版本最稳妥的方式是会话内显式设置 JAVA_HOME,不改全局默认。切到 11 验证:

export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
export PATH=$JAVA_HOME/bin:$PATH
java -version

实测回显:

openjdk version "11.0.32.1" 2026-08-18
OpenJDK Runtime Environment (build 11.0.32.1+1-post-1ubuntu1-22.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 11.0.32.1+1-post-1ubuntu1-22.04-Ubuntu, mixed mode, sharing)

在 JDK 11 下编译并运行同一个 HashBag 示例,验证库在 11 上可用。示例 BagDemo11.java 源码:

import org.apache.commons.collections4.Bag;
import org.apache.commons.collections4.bag.HashBag;

public class BagDemo11 {
    public static void main(String[] args) {
        Bag<String> bag = new HashBag<>();
        bag.add("apple", 3);
        System.out.println("run under JDK 11: getCount(apple) = " + bag.getCount("apple"));
    }
}

先切回 17 恢复环境再切 11 的操作相同(把 JAVA_HOME 换成 /usr/lib/jvm/java-17-openjdk-amd64 即可)。JDK 11 下的编译与运行:

javac -nowarn -cp commons-collections4-4.6.0/commons-collections4-4.6.0.jar BagDemo11.java
java -cp .:commons-collections4-4.6.0/commons-collections4-4.6.0.jar BagDemo11
javap -v BagDemo11.class | grep major

实测回显:

run under JDK 11: getCount(apple) = 3
  major version: 55

⚠️ 注意:用 JDK 17 编译出的 class(major 61)直接丢给 JDK 11 运行会报 UnsupportedClassVersionError(class file version 61.0 与 55.0 不匹配)。保证「编译 JDK 与运行 JDK 一致」,或像 5.1 的 pom 那样把 maven.compiler.source/target 压到 8,产物即可在 8/11/17 通用。

七、卸载与清理

按安装的逆序清理,每步都给验证命令。先删示例与下载物:

rm -rf /root/collections-lab /tmp/maven-demo

卸载演示用的 JDK 11(若生产需要 11 可跳过此步):

sudo apt-get remove --purge -y openjdk-11-jdk-headless openjdk-11-jre-headless
update-alternatives --list java

实测输出节选(实测首尾):

After this operation, 258 MB disk space will be freed.
/usr/lib/jvm/java-17-openjdk-amd64/bin/java

update-alternatives 只剩 17 一条,说明 11 已卸载干净。再卸 Maven:删软链与 /opt 安装目录,然后验证 mvn 不可用:

sudo rm -f /usr/local/bin/mvn
sudo rm -rf /opt/apache-maven-3.9.16
command -v mvn

实测回显(command -v 无输出且退出码非 0,bash 打印未找到提示):

mvn: not found

如需彻底移除 JDK 17(仅当本机不再需要任何 Java 环境):sudo apt-get remove --purge -y openjdk-17-jdk-headless,验证方式同上。~/.m2 是 Maven 本地仓库缓存,确认不再使用 Maven 后可一并删除。

八、常见问题 FAQ

Q1: 3.x 还能用吗?为什么文档总强调 4.x?3.x 的包名是 org.apache.commons.collections,4.x 改为 org.apache.commons.collections4(Maven 坐标也从 commons-collections 变为 org.apache.commons:commons-collections4),二者二进制不兼容。更重要的是安全史:3.x 的 InvokerTransformer 等 functors 类实现了 Serializable,在 Java 反序列化场景被 ysoserial 的 CommonsCollections 系列利用链反复利用(CVE-2015-6420 相关),3.2.2 虽做了部分修补但该系列已 EOL;4.1 起 functors 类不再实现 Serializable,从根源阻断了这类利用链(本篇 2.1 表中的 3.2.2 与 4.6.0 jar 可直接 javap 对比验证)。新项目必须用 4.x。

Q2: 编译 HashBag 示例时提示 deprecated 是怎么回事?4.6.0 起官方把 Bag/HashBag 标记为过时,推荐迁移到等价的 MultiSet/HashMultiSet(对应 4.6.0 RELEASE-NOTES 中 COLLECTIONS-893 的 MultiSet 能力补齐),计数语义与 getCount 用法完全一致。已有代码可继续用,新代码建议直接用 HashMultiSet。

Q3: 不装 Maven 可以用库吗?可以,5.2 的方案B就是:官方 bin 包 + javac/java -cp 直跑,零额外工具。只是失去依赖管理与构建生命周期,适合单文件验证与离线环境。

Q4: 运行报 UnsupportedClassVersionError 怎么办?这是编译用高版本 JDK、运行用低版本 JRE 导致的(如 17 编译、11 运行)。用 java -version 与 javac -version 双向核对当前会话版本,或按第六节用 JAVA_HOME 显式切换;跨版本交付时在 pom 固定 maven.compiler.source/target=8。

九、参考链接

  1. Apache Commons Collections 官方主页:https://commons.apache.org/proper/commons-collections/
  2. 官方发行包目录(含 sha512):https://downloads.apache.org/commons/collections/
  3. Maven 中央仓库 commons-collections4:https://mvnrepository.com/artifact/org.apache.commons/commons-collections4
  4. 4.6.0 RELEASE-NOTES(Java 8+ 要求与 Bag 迁移说明):https://downloads.apache.org/commons/collections/RELEASE-NOTES.txt
  5. 历史版本归档(3.2.2 与 4.4 等日期依据):https://archive.apache.org/dist/commons/collections/binaries/
  6. Apache Maven 下载页:https://maven.apache.org/download.cgi