Ubuntu 22.04 安装 Apache Commons Pool 指南

在 Ubuntu 22.04 上从零安装 Apache Commons Pool 2.13.1,覆盖 JDK 17 与 Maven 环境、Maven 依赖与官方 bin 包两种方案、借还复用最小验证、多版本管理与卸载,命令回显均实测通过。

Apache Commons PoolApache Commons Pool2026/10/15

Ubuntu 22.04 安装 Apache Commons Pool 指南

目标:在 Ubuntu 22.04 上从零搭建 Apache Commons Pool 2.13.1 的开发与运行环境(JDK 17 + Maven 3.6.3 + 官方依赖),并跑通对象借还、空闲复用与池统计的核心验证;本文全部命令与回显均已在 Ubuntu 22.04 实测通过。

Apache Commons Pool 是 Apache Commons 项目下的对象池化框架,提供 GenericObjectPool(通用对象池)与 GenericKeyedObjectPool(按键分池)两类实现,把「昂贵对象的创建—复用—回收」统一托管。它是纯 Java 库,没有独立进程与常驻服务,安装的本质就是「装好 JDK/构建工具 → 引入依赖 → 写最小验证代码 → 编译运行」。2.x 系列(包名 org.apache.commons.pool2,Maven 坐标 commons-pool2)是完全重写的主线版本,1.x 仅作遗留兼容。本文给出两种落地方式:面向开发的 Maven 依赖方案,以及面向无构建体系场景的官方 bin 包 + jar 直跑方案。

一、环境信息

本节先固定可复现的基线环境,后续所有命令均在此环境执行。列出操作系统、架构、JDK、构建工具与组件版本,便于读者对照复现。

  • 操作系统:Ubuntu 22.04.5 LTS(PRETTY_NAME="Ubuntu 22.04.5 LTS")
  • 架构:x86_64
  • JDK:OpenJDK 17.0.20.1(apt 包 openjdk-17-jdk,版本号 17.0.20.1+1-1~22.04)
  • 构建工具:Apache Maven 3.6.3
  • 组件版本:commons-pool2 2.13.1
  • 官方下载目录:https://downloads.apache.org/commons/pool/
  • Maven 坐标:org.apache.commons:commons-pool2:2.13.1
  • 验证用工作目录:/root/commons-pool-demo(Maven 工程)、/root/pool-exp(实验程序)、/root/jar-run(jar 直跑)

系统与架构确认(实时回显):

cat /etc/os-release | head -3
PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
uname -m
x86_64

💡 说明:Commons Pool 是库而非服务,环境中不存在需要常驻的守护进程;「安装完成」的判定标准是可编译并运行一个调用其 API 的最小程序,而不是某个端口处于监听状态。

二、前置条件

本节说明安装前必须满足的条件。Ubuntu 22.04 自带可用的软件源,联网即可通过 apt 获取 JDK 与 Maven。

  1. 具有 root 或 sudo 权限的 Ubuntu 22.04 系统。
  2. 可访问 Ubuntu 官方软件源(apt update 能正常拉取索引)。
  3. 可访问 Apache 官方下载站 downloads.apache.org 与 Maven 中央仓库 repo1.maven.org。
  4. 至少 2 GB 可用磁盘空间(JDK + Maven + 依赖合计约 500 MB)。

对 Maven 中央仓库的连通性与速率确认(实时回显):

curl -s -o /dev/null -w "%{http_code} %{speed_download}B/s\n" --max-time 30 https://repo1.maven.org/maven2/org/apache/commons/commons-pool2/2.13.1/commons-pool2-2.13.1.jar
200 90722B/s

对官方发布目录的版本清单确认(实时回显):

curl -s --max-time 30 https://downloads.apache.org/commons/pool/binaries/ | grep -oE "href=\"[^\"]+\"" | grep -vE "href=\"(http|#|\?|/commons)"
href="commons-pool2-2.13.1-bin.tar.gz"
href="commons-pool2-2.13.1-bin.tar.gz.asc"
href="commons-pool2-2.13.1-bin.tar.gz.sha512"
href="commons-pool2-2.13.1-bin.zip"
href="commons-pool2-2.13.1-bin.zip.asc"
href="commons-pool2-2.13.1-bin.zip.sha512"
href="commons-pool2-2.6.2-bin.tar.gz"
href="commons-pool2-2.6.2-bin.tar.gz.asc"
href="commons-pool2-2.6.2-bin.tar.gz.sha512"
href="commons-pool2-2.6.2-bin.zip"
href="commons-pool2-2.6.2-bin.zip.asc"
href="commons-pool2-2.6.2-bin.zip.sha512"

三、版本选型说明

本节给出 Commons Pool 的版本谱系,帮助读者在 1.x 与 2.x 之间做出选择。官方 binaries 目录当前提供 2.13.1 与 2.6.2 两个版本线的安装包(见第二章回显),Maven 中央仓库的元数据确认最新发布版(实时回显):

curl -s --max-time 30 https://repo1.maven.org/maven2/org/apache/commons/commons-pool2/maven-metadata.xml | grep -E "<latest>|<release>"
    <latest>2.13.1</latest>
    <release>2.13.1</release>

官方 RELEASE-NOTES 对 JDK 基线的声明(实时回显):

curl -s --max-time 30 https://downloads.apache.org/commons/pool/RELEASE-NOTES.txt | sed -n "11,13p"
Versions 2.7.x and up require Java 8 or later.
Version 2.6.x requires Java 7 or above.
版本线最新版JDK 基线包名/坐标适用场景
2.x(当前主线)2.13.1Java 8+org.apache.commons.pool2 / org.apache.commons:commons-pool2所有新项目默认选择
2.6.x(旧 2.x 线)2.6.2Java 7+同上需兼容 Java 7 的遗留工程
1.x(已停止维护)1.6Java 5+org.apache.commons.pool / commons-pool:commons-pool极老项目兼容,不建议新用

关键差异与选型:2.x 相比 1.x 重写了整个池化实现,补齐了实例追踪(PooledObject 状态机)、池监控(JMX MBean)与驱逐策略(EvictionPolicy)三大能力,且 API 层以 Duration 参数逐步替代毫秒参数。本文实际采用 2.13.1,理由是它是 Maven 中央仓库当前 latest/release 版本,对 JDK 17 完全兼容,实测编译运行零告警。

四、方案 A:Maven 依赖安装(在线,推荐)

本节面向常规 Java 项目开发,通过 apt 安装 JDK 与 Maven,再用 Maven 坐标引入 commons-pool2 依赖并跑通最小验证程序。这是最贴合工程实践的方式。

4.1 方案说明

方案 A 的链路是:apt 安装 openjdk-17-jdk 与 maven → 在 pom.xml 中声明 org.apache.commons:commons-pool2:2.13.1 → Maven 自动从中央仓库下载 jar 到本地仓库 → 编译并运行验证程序。优点是版本由 pom 统一管控、依赖自动解析;缺点是首次构建需要联网。

4.2 安装 JDK 17

先刷新索引,再安装 openjdk-17-jdk(实时回显):

apt-get update | tail -3
Get:18 http://archive.ubuntu.com/ubuntu jammy-backports/main amd64 Packages [82.9 kB]
Fetched 49.0 MB in 6s (8196 kB/s)
Reading package lists...
apt-get install -y openjdk-17-jdk
# 输出节选(实测首尾)
Reading package lists...
Building dependency tree...
Reading state information...
The following additional packages will be installed:
  adwaita-icon-theme alsa-topology-conf alsa-ucm-conf at-spi2-core
  ca-certificates ca-certificates-java dbus dbus-user-session
  dconf-gsettings-backend dconf-service default-jre-headless dmsetup
  fontconfig fontconfig-config fonts-dejavu-core fonts-dejavu-extra
Setting up maven (3.6.3-5) ...
Setting up openjdk-17-jdk-headless:amd64 (17.0.20.1+1-1~22.04) ...
Setting up openjdk-17-jdk:amd64 (17.0.20.1+1-1~22.04) ...

安装后确认版本:

java -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)

验证点:java -version 能输出 17.0.x 即表示 JDK 就绪;若仍指向旧版本,用 update-alternatives --config java 选择 17。

4.3 安装 Maven

apt-get install -y maven && mvn -version | head -3
maven is already the newest version (3.6.3-5).
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 17.0.20.1, vendor: Ubuntu, runtime: /usr/lib/jvm/java-17-openjdk-amd64

验证点:Java version 一行显示 17.0.20.1,说明 Maven 已绑定到 JDK 17,无需额外设置 JAVA_HOME。

4.4 创建工程并引入依赖

建立一个标准 Maven 工程,pom.xml 中声明 commons-pool2 依赖。commons-pool2 零传递依赖,声明这一项即引入全部能力。

mkdir -p /root/commons-pool-demo/src/main/java && cd /root/commons-pool-demo

pom.xml(完整内容,文件路径 /root/commons-pool-demo/pom.xml):

<?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.pool</groupId>
  <artifactId>commons-pool-demo</artifactId>
  <version>1.0.0</version>
  <packaging>jar</packaging>

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

  <dependencies>
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-pool2</artifactId>
      <version>2.13.1</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.11.0</version>
      </plugin>
    </plugins>
  </build>
</project>

逐项说明关键配置:

  • org.apache.commons:commons-pool2:2.13.1:唯一运行期依赖,Maven 会自动下载并缓存到 ~/.m2/repository/org/apache/commons/commons-pool2/2.13.1/。
  • maven.compiler.source/target=17:按 JDK 17 编译;2.13.1 的 JDK 基线是 Java 8(见第三章),如需兼容更老运行环境可下调到 1.8。
  • maven-compiler-plugin 显式固定为 3.11.0:避免老 Maven 默认绑定的旧插件行为不一致。
  • project.build.sourceEncoding=UTF-8:源码含中文注释/字符串时防止按 POSIX 默认编码编译报错。

4.5 最小验证代码

验证程序 PoolCheck.java(文件路径 /root/commons-pool-demo/src/main/java/PoolCheck.java)演示对象池最核心的行为:首次借出触发真实创建、归还进入空闲队列、二次借出按 LIFO 顺序复用且不再新建:

import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class PoolCheck {

    /* 模拟创建成本 20ms 的昂贵连接对象 */
    static class Conn {
        final int id;
        Conn(int id) { this.id = id; }
    }

    static class ConnFactory extends BasePooledObjectFactory<Conn> {
        final AtomicInteger seq = new AtomicInteger();
        @Override public Conn create() throws Exception {
            Thread.sleep(20);
            return new Conn(seq.incrementAndGet());
        }
        @Override public PooledObject<Conn> wrap(Conn c) {
            return new DefaultPooledObject<>(c);
        }
    }

    public static void main(String[] args) throws Exception {
        GenericObjectPoolConfig<Conn> cfg = new GenericObjectPoolConfig<>();
        cfg.setMaxTotal(4);
        GenericObjectPool<Conn> pool = new GenericObjectPool<>(new ConnFactory(), cfg);

        // 首次借出:池为空,触发 3 次对象创建
        List<Conn> held = new ArrayList<>();
        StringBuilder first = new StringBuilder();
        for (int i = 0; i < 3; i++) {
            Conn c = pool.borrowObject();
            held.add(c);
            first.append("Conn-").append(c.id);
            if (i < 2) first.append(", ");
        }
        System.out.println("首次借出: " + first + "  numActive=" + pool.getNumActive()
                + ", createdCount=" + pool.getCreatedCount());

        // 全部归还
        for (Conn c : held) {
            pool.returnObject(c);
        }
        System.out.println("归还后: numIdle=" + pool.getNumIdle() + ", numActive=" + pool.getNumActive());

        // 二次借出:全部复用空闲对象(LIFO 顺序),不再新建
        StringBuilder second = new StringBuilder();
        for (int i = 0; i < 3; i++) {
            Conn c = pool.borrowObject();
            second.append("Conn-").append(c.id);
            if (i < 2) second.append(", ");
        }
        System.out.println("二次借出: " + second + "  createdCount=" + pool.getCreatedCount()
                + "(复用空闲对象,未新建)");

        System.out.println("commons-pool2 OK");
        pool.close();
    }
}

💡 技术拓展:Java 生态里做「对象池化」的常见方案对比如下——

方案定位特点适用场景
Commons Pool 2.x通用对象池框架工厂钩子 + 驱逐 + JMX 全齐,语言无关数据库外的各类昂贵对象(连接、会话、缓冲区、解析器)
Commons Pool 1.x上一代实现无 PooledObject 状态机,性能弱于 2.x仅维护遗留系统
Commons DBCP2JDBC 连接池构建在 Commons Pool 2 之上纯 JDBC 场景
HikariCPJDBC 连接池自研无锁结构,不依赖 Commons Pool追求极致吞吐的 JDBC 场景

本文采用 Commons Pool 2.x,理由是它提供通用的池化抽象(PooledObjectFactory + GenericObjectPool),能池化任意 Java 对象而非局限于 JDBC,并且是 DBCP2、Redis 客户端(Jedis/Lettuce 池化模式)等生态组件的底层基础。

4.6 编译与运行验证

编译(首次构建需下载依赖与插件,实测耗时约 1 分 36 秒;依赖已缓存后重建在 5 秒级):

mvn -B -q compile; echo "EXIT=$?"
EXIT=0

查看依赖树(确认零传递依赖):

mvn -B dependency:tree 2>&1 | grep -E "^\[INFO\] (com\.example|\\\- )"
[INFO] com.example.pool:commons-pool-demo:jar:1.0.0
[INFO] \- org.apache.commons:commons-pool2:jar:2.13.1:compile

解读:依赖树中除工程自身外只有 commons-pool2:2.13.1 一个节点,零传递依赖,不会拖入任何其他 jar。

运行并观察完整回显:

P=$HOME/.m2/repository/org/apache/commons/commons-pool2/2.13.1/commons-pool2-2.13.1.jar
java -Dfile.encoding=UTF-8 -Dstdout.encoding=UTF-8 -cp target/classes:$P PoolCheck
首次借出: Conn-1, Conn-2, Conn-3  numActive=3, createdCount=3
归还后: numIdle=3, numActive=0
二次借出: Conn-3, Conn-2, Conn-1  createdCount=3(复用空闲对象,未新建)
commons-pool2 OK

结果解读:三组输出全部符合池化预期——首次借出 createdCount=3(创建与借出数一致)、归还后 numIdle=3、二次借出按 LIFO 倒序拿到 Conn-3, Conn-2, Conn-1 且 createdCount 仍为 3(零新建)。这表示 commons-pool2 2.13.1 已在 JDK 17 上完整可用。

💡 说明:-Dfile.encoding=UTF-8 -Dstdout.encoding=UTF-8 用于固定中文输出的字符集。若服务器 LANG 已为 UTF-8 locale 可省略;默认 POSIX locale 下省略会出现中文变问号(实测复现见《Apache Commons Pool 2.13.1 快速入门与集成示例》3.2 节)。

五、方案 B:官方 bin 包 + jar 直跑(离线友好)

本节面向没有 Maven/构建体系的场景,直接使用官方发布的 jar 包,用 javac + java 完成编译运行,不依赖任何构建工具。

5.1 方案说明

链路是:从 downloads.apache.org 下载官方 bin 包 → 校验 sha512 → 解压得到 commons-pool2-2.13.1.jar → 用 javac -cp 编译源码 → 用 java -cp 运行。适用于离线环境、脚本化部署或纯粹想「拿到 jar 就能用」的读者。

5.2 下载与完整性校验

cd /root && curl -sO --max-time 120 https://downloads.apache.org/commons/pool/binaries/commons-pool2-2.13.1-bin.tar.gz
curl -sO --max-time 30 https://downloads.apache.org/commons/pool/binaries/commons-pool2-2.13.1-bin.tar.gz.sha512
ls -l commons-pool2-2.13.1-bin.tar.gz
-rw-r--r-- 1 root root 1840650 Oct 15 01:06 commons-pool2-2.13.1-bin.tar.gz

校验 sha512(期望值与实测值必须逐字一致):

echo "期望: $(cat commons-pool2-2.13.1-bin.tar.gz.sha512)"
echo "实测: $(sha512sum commons-pool2-2.13.1-bin.tar.gz | awk '{print $1}')"
期望: 98afb2f67245b65039fb2cbe58dd0e1b1afbc55164dc010948a2a5d72a814e71fbf1c52e88859f812baa758fd12b17c90e86c266204a0d1a0e6e772d19624c5f
实测: 98afb2f67245b65039fb2cbe58dd0e1b1afbc55164dc010948a2a5d72a814e71fbf1c52e88859f812baa758fd12b17c90e86c266204a0d1a0e6e772d19624c5f

⚠️ 注意:若 sha512 不一致,说明下载包损坏或被篡改,须删除后重新下载;切勿跳过校验直接使用。

5.3 解压

tar xzf commons-pool2-2.13.1-bin.tar.gz && ls commons-pool2-2.13.1/
LICENSE.txt
NOTICE.txt
RELEASE-NOTES.txt
apidocs
commons-pool2-2.13.1-javadoc.jar
commons-pool2-2.13.1-sources.jar
commons-pool2-2.13.1-test-sources.jar
commons-pool2-2.13.1-tests.jar
commons-pool2-2.13.1.jar

主 jar 为 commons-pool2-2.13.1.jar(156457 字节,实测):

ls -l commons-pool2-2.13.1/commons-pool2-2.13.1.jar
-rw-r--r-- 1 root root 156457 Dec 30  2025 commons-pool2-2.13.1/commons-pool2-2.13.1.jar

5.4 javac 编译与 java 运行

用官方 jar 作为编译与运行期 classpath:

mkdir -p /root/jar-run && cd /root/jar-run
cp /root/commons-pool2-2.13.1/commons-pool2-2.13.1.jar .
cp /root/commons-pool-demo/src/main/java/PoolCheck.java .
javac -encoding UTF-8 -cp commons-pool2-2.13.1.jar -d out PoolCheck.java

编译无任何告警输出。运行:

java -Dfile.encoding=UTF-8 -Dstdout.encoding=UTF-8 -cp out:commons-pool2-2.13.1.jar PoolCheck
首次借出: Conn-1, Conn-2, Conn-3  numActive=3, createdCount=3
归还后: numIdle=3, numActive=0
二次借出: Conn-3, Conn-2, Conn-1  createdCount=3(复用空闲对象,未新建)
commons-pool2 OK

验证点:java -cp 一行成功打印四组结果,且无 NoClassDefFoundError,说明 jar 直跑可用;与方案 A 的 Maven 运行结果完全一致。

5.5 Maven 中央仓库 jar 的独立获取(可选)

若只想从 Maven 中央仓库获取单个 jar 而不使用构建工具,可直接下载并校验 sha1:

cd /root/jar-run && curl -sO --max-time 60 https://repo1.maven.org/maven2/org/apache/commons/commons-pool2/2.13.1/commons-pool2-2.13.1.jar
curl -sO --max-time 30 https://repo1.maven.org/maven2/org/apache/commons/commons-pool2/2.13.1/commons-pool2-2.13.1.jar.sha1
echo "期望: $(cat commons-pool2-2.13.1.jar.sha1)"
echo "实测: $(sha1sum commons-pool2-2.13.1.jar | awk '{print $1}')"
期望: cf7e8c0242d4c483c42c083b8188ab360ab60f9a
实测: cf7e8c0242d4c483c42c083b8188ab360ab60f9a

六、方案对比与选择建议

本节汇总两种方案的差异,给出选型建议。两种方案产出的是同一份 commons-pool2 2.13.1 代码,差别仅在获取与装配方式。

维度方案 A:Maven 依赖方案 B:官方 bin 包 + jar 直跑
运行期依赖Maven 自动解析手工把 jar 放入 classpath
是否联网首次构建需联网仅下载时需要联网
依赖版本管控pom 统一声明,可锁版本无,靠文件命名区分
传递依赖零传递依赖(实测依赖树仅自身一个节点)同左,无额外负担
可复现产物mvn compile 产出 target/classesjavac 产出 class + 引用 jar
适用场景常规工程开发离线脚本、临时验证、无构建体系

选型建议:若项目有构建体系(Maven/Gradle),一律选方案 A,版本管控与打包全部自动化;若在无构建工具的老旧服务器上临时验证,或需要把 jar 手工嵌入既有脚本,选方案 B。commons-pool2 恰好零传递依赖,方案 B 的使用成本在所有 Commons 组件里几乎是最低的。两者也可共存——用方案 A 开发、用方案 B 分发 jar。

七、配置说明

本节说明 Commons Pool 使用中真正需要设置的「配置」。它是库而非服务,没有独立配置文件,全部行为通过代码参数或 JDK 环境变量控制。

环境变量 JAVA_HOME(Maven 定位 JDK 的优先来源)。默认会话中该变量为空(实测回显):

echo "JAVA_HOME=$JAVA_HOME"
JAVA_HOME=

此时 Maven 仍能正常工作,是因为 apt 版 Maven 通过 PATH 中的 java(由 update-alternatives 指向 JDK 17,见 4.3 节 mvn -version 回显的 runtime 一行)完成 JDK 定位。若手工安装 JDK 或需要显式固定 JDK 路径,可按下面方式显式导出(实测回显):

export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 && echo "JAVA_HOME=$JAVA_HOME"
JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64

逐项说明:

  • JAVA_HOME:Maven 定位 JDK 的优先来源。Ubuntu 官方源的 Maven 自带兼容逻辑,JAVA_HOME 为空时按 PATH 中的 java 定位,实测无需手工设置即可构建;仅当手工安装 JDK 或 Maven 报「找不到 JDK」时再显式导出。
  • 代码级「参数」:GenericObjectPoolConfig 的 maxTotal/maxIdle/maxWait、testOnBorrow 等检测开关、驱逐线程周期与 LIFO 借出顺序等,全部通过构造池时的 Config 对象控制,无外部配置文件。各参数的完整默认值与实测行为见《Apache Commons Pool 2.13.1 配置参数详解》。

八、多版本管理

多版本共存靠「隔离依赖坐标版本 + 隔离 jar 文件名」实现,无需切换全局软链。

Maven 本地仓库中不同版本的 commons-pool2 并列存放,互不覆盖。先用 dependency:get 拉入一个旧版本,再查看目录(实时回显):

mvn -q -B dependency:get -Dartifact=org.apache.commons:commons-pool2:2.6.2
ls -1 $HOME/.m2/repository/org/apache/commons/commons-pool2/
2.13.1
2.6.2

要点:工程要用哪个版本,只在 pom.xml 的 <dependency><version> 中改数字即可,其余版本仍留在本地仓库供其他工程复用。jar 直跑场景,把不同版本的 jar(如 commons-pool2-2.6.2.jar)分目录存放,运行时按需拼 classpath。

切换工程依赖版本并验证生效:

cd /root/commons-pool-demo && mvn -B dependency:tree 2>&1 | grep -E "^\[INFO\] \\\- "
[INFO] \- org.apache.commons:commons-pool2:jar:2.13.1:compile

九、常见问题(FAQ)

Q1:borrowObject 抛出 NoSuchElementException: Timeout waiting for idle object 是安装问题吗? 不是。这是池容量(maxTotal)被占满且等待超时的正常业务表现:对象全在业务手里,maxWait 到点后池拒绝继续等待。要么归还对象、要么调大 maxTotal/maxWait。若把 blockWhenExhausted 关掉,则不等待立即抛 Pool exhausted。两类异常的实测回显见《Apache Commons Pool 2.13.1 配置参数详解》5.2 节。

Q2:运行时报 Could not find or load main class PoolCheck? 说明运行期 classpath 未包含编译产物或 commons-pool2 jar。jar 直跑时确认命令为 java -cp out:commons-pool2-2.13.1.jar PoolCheck(out 为 javac -d 指定的输出目录);Maven 方式则要确认 mvn compile 真正执行了 Compiling 1 source file,而不是 Nothing to compile 的空构建(实测复现与排障见《Apache Commons Pool 2.13.1 快速入门与集成示例》3.1 节)。

Q3:中文输出显示为问号? 默认 POSIX locale 下 JVM 会用 ASCII 输出中文。解决:运行时加 -Dfile.encoding=UTF-8 -Dstdout.encoding=UTF-8,或把系统 locale 调成 UTF-8(export LANG=C.UTF-8)。

Q4:commons-pool2 2.13.1 能不能跑在 JDK 8 上? 可以。官方 RELEASE-NOTES 声明 2.7.x 及以上要求 Java 8 或更高(见第三章回显),2.13.1 属于 2.7.x+ 系列;本文用 JDK 17 属于更高基线,兼容性不受影响。

Q5:Maven 下载依赖很慢怎么办? 本文实测直连 repo1.maven.org 下载 commons-pool2 主 jar 约 90 KB/s(约 1.7 秒,见第二章回显),主依赖体积小影响有限;首次构建慢主要来自插件下载。可在 ~/.m2/settings.xml 配置国内镜像(如阿里云 https://maven.aliyun.com/repository/public)加速。

十、卸载与清理

Commons Pool 本身不产生系统级安装,卸载即移除依赖与本地文件。

移除工程、实验目录与 bin 包(实时回显):

rm -rf /root/commons-pool-demo /root/pool-exp /root/jar-run /root/commons-pool2-2.13.1 /root/commons-pool2-2.13.1-bin.tar.gz
ls /root/commons-pool-demo 2>&1
ls: cannot access '/root/commons-pool-demo': No such file or directory

移除 Maven 本地仓库中的 commons-pool2(影响所有工程,慎用):

rm -rf $HOME/.m2/repository/org/apache/commons/commons-pool2

卸载 JDK 与 Maven(仅当不再需要)。先以 -s 预演确认将删除的包,无误后去掉 -s 真正执行:

apt-get -s purge -y openjdk-17-jdk maven
# 输出节选(实测首尾)
The following packages will be REMOVED:
  maven* openjdk-17-jdk*
0 upgraded, 0 newly installed, 2 to remove and 1 not upgraded.
Purg maven [3.6.3-5]
Purg openjdk-17-jdk [17.0.20.1+1-1~22.04]

确认无误后真正卸载(实际生产环境执行):

apt-get purge -y openjdk-17-jdk maven && apt-get autoremove -y

十一、参考链接

  1. Apache Commons Pool 官方主页:https://commons.apache.org/proper/commons-pool/
  2. Apache Commons Pool 官方下载目录:https://downloads.apache.org/commons/pool/
  3. Commons Pool 2.13.1 发布说明:https://downloads.apache.org/commons/pool/RELEASE-NOTES.txt
  4. Commons Pool Javadoc(GenericObjectPool/GenericKeyedObjectPool/PooledObjectFactory):https://commons.apache.org/proper/commons-pool/apidocs/
  5. Maven 中央仓库 commons-pool2 坐标:https://repo1.maven.org/maven2/org/apache/commons/commons-pool2/
  6. OpenJDK 17 安装包(Ubuntu 官方源):apt-cache show openjdk-17-jdk