Ubuntu 22.04 安装 Apache Commons BeanUtils 指南

在 Ubuntu 22.04 从零安装 Commons BeanUtils 1.11.0:apt 装 OpenJDK 17 与 Maven,Maven 依赖与发行包双方案,含 sha512 校验、依赖补齐、最小验证与卸载,全部命令实测。

Apache Commons BeanUtilsApache Commons BeanUtils2026/10/13

Ubuntu 22.04 安装 Apache Commons BeanUtils 指南

目标:在 Ubuntu 22.04 服务器上从零搭建可编译、可运行 Apache Commons BeanUtils 的 Java 环境,覆盖「Maven 依赖」与「官方发行包手动安装」两种方案、sha512 完整性校验、运行期依赖补齐、最小验证代码、多版本管理与卸载,已在 Ubuntu 22.04(OpenJDK 17.0.20.1、Maven 3.6.3)实测通过。

一、环境信息

本篇所有命令与回显均在以下环境中实测采集,复现时请保持相近版本:

  • 操作系统:Ubuntu 22.04.5 LTS(jammy),x86_64,内核 6.8.0-138-generic
  • JDK:OpenJDK 17.0.20.1(openjdk-17-jdk,apt 官方仓库,另备 OpenJDK 11.0.32.1 供多版本切换)
  • 构建工具:Apache Maven 3.6.3(maven,apt 官方仓库)
  • 组件版本:Apache Commons BeanUtils 1.11.0(downloads.apache.org 当前稳定线最新版,2026-10 实测)
  • 实验目录:/opt/lab/beanutils(方案 A 工程 proj,方案 B 目录 manual,发行包目录 dist)
  • 执行用户:root

二、版本选型

Commons BeanUtils 的发布版以 Java Bean 属性反射工具为核心,选型先确认版本线与 JDK 要求:

版本发布状态对 JDK 要求运行期依赖获取渠道
1.11.0稳定版(本篇实测采用)Java 8 及以上commons-logging 1.3.5、commons-collections 3.2.2downloads.apache.org 与 Maven 中央仓库
2.0.0-M2里程碑预览(新坐标 commons-beanutils2)以官方发布说明为准以其发行包内说明为准downloads.apache.org 的 binaries 目录

逐项说明:

  • 1.11.0:downloads.apache.org/commons/beanutils/ 目录下当前唯一的 1.x 稳定版,与 Maven 中央仓库 <latest>1.11.0</latest> 一致;实测其字节码 major version: 52(即 Java 8 编译),可在 Java 8/11/17 运行。
  • 2.0.0-M2:属于新一代 commons-beanutils2 坐标的里程碑预览,坐标与 1.x 不同,生产环境暂不建议,本篇不展开。
  • 选型结论:以 1.11.0 为准,下文全部实测均基于该版本。

验证中央仓库最新版与本仓库字节码版本:

# curl -s --max-time 20 "https://repo.maven.apache.org/maven2/commons-beanutils/commons-beanutils/maven-metadata.xml" | grep -E 'latest|release'
    <latest>1.11.0</latest>
    <release>1.11.0</release>
# javap -v -cp dist/commons-beanutils-1.11.0/commons-beanutils-1.11.0.jar org.apache.commons.beanutils.BeanUtils 2>/dev/null | grep -m1 major
  major version: 52

major version: 52 说明该库按 Java 8 字节码发布,对 JDK 11、17 向下兼容,本篇环境选 JDK 17 无兼容问题。

三、安装 JDK 与 Maven

3.1 更新软件源索引

先刷新 apt 索引,保证后续安装能命中最新可用包:

# apt-get update | tail -3
Hit:3 http://archive.ubuntu.com/ubuntu jammy-updates InRelease
Hit:4 http://archive.ubuntu.com/ubuntu jammy-backports InRelease
Reading package lists...

回显末尾出现 Reading package lists 且无报错行,说明索引刷新完成。

3.2 安装 JDK、Maven 与下载工具

一条命令装齐 JDK 17 与 Maven:

# apt-get install -y openjdk-17-jdk maven
maven is already the newest version (3.6.3-5).
openjdk-17-jdk is already the newest version (17.0.20.1+1-1~22.04).

本次实测基线已带 JDK 17 与 Maven,因此回显为 already the newest version;curl、wget 在本机基线缺失,是实际新装的,真实安装回显如下:

# apt-get install -y curl wget
Setting up libcurl4:amd64 (7.81.0-1ubuntu1.29) ...
Setting up curl (7.81.0-1ubuntu1.29) ...

两种回显都正常:前者说明包已在系统内,后者是真实解包安装过程,只要命令退出码为 0 即可。

3.3 验证安装

分别验证编译器、运行时与构建工具:

# 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)
# javac -version
javac 17.0.20.1
# mvn -v
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
Default locale: en_US, platform encoding: ANSI_X3.4-1968
OS name: "linux", version: "6.8.0-138-generic", arch: "amd64", family: "unix"

注意 platform encoding: ANSI_X3.4-1968,说明当前 shell 未启用 UTF-8 locale,直接输出中文会变问号,解法见 3.4 与 FAQ Q2。

3.4 多版本管理(可选)

基线同时装有 OpenJDK 11,用 update-alternatives 管理切换:

# update-alternatives --list java
/usr/lib/jvm/java-11-openjdk-amd64/bin/java
/usr/lib/jvm/java-17-openjdk-amd64/bin/java

切到 Java 11 并验证,再切回 17:

# update-alternatives --set java /usr/lib/jvm/java-11-openjdk-amd64/bin/java
update-alternatives: using /usr/lib/jvm/java-11-openjdk-amd64/bin/java to provide /usr/bin/java (java) in manual mode
# java -version | head -1
openjdk version "11.0.32.1" 2026-08-18
# update-alternatives --set java /usr/lib/jvm/java-17-openjdk-amd64/bin/java
update-alternatives: using /usr/lib/jvm/java-17-openjdk-amd64/bin/java to provide /usr/bin/java (java) in manual mode
# java -version | head -1
openjdk version "17.0.20.1" 2026-08-18

Commons BeanUtils 1.11.0 是 Java 8 字节码,11 与 17 都能运行;日常建议默认 17,需要验证老环境兼容性时再临时切 11。

四、方案 A:Maven 依赖接入

Maven 方案由中央仓库自动拉取主 jar 与全部运行期依赖,是首选接入方式。

4.1 创建工程骨架

创建目录并准备 pom.xml:

# mkdir -p /opt/lab/beanutils/proj/src/main/java/com/example/beanutils
# cd /opt/lab/beanutils/proj

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</groupId>
  <artifactId>beanutils-lab</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>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>commons-beanutils</groupId>
      <artifactId>commons-beanutils</artifactId>
      <version>1.11.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.codehaus.mojo</groupId>
        <artifactId>exec-maven-plugin</artifactId>
        <version>3.1.0</version>
      </plugin>
    </plugins>
  </build>
</project>

逐项说明:

  • maven.compiler.source/target 设为 17,与已装 JDK 匹配;project.build.sourceEncoding 设 UTF-8,避免中文源码乱码。
  • 唯一业务依赖 commons-beanutils:1.11.0,其余两个插件显式固定版本:实测发现不固定版本时,Maven 会解析到很旧的编译插件(见 FAQ Q3)。
  • exec-maven-plugin 用于第 4.3 步与后续示例的直接运行。

把示例源码放入 src/main/java/com/example/beanutils/(最小验证代码见第七章),目录结构核对:

# find /opt/lab/beanutils/proj -type f | sort
/opt/lab/beanutils/proj/pom.xml
/opt/lab/beanutils/proj/src/main/java/com/example/beanutils/ConverterDemo.java
/opt/lab/beanutils/proj/src/main/java/com/example/beanutils/CopyDemo.java
/opt/lab/beanutils/proj/src/main/java/com/example/beanutils/DynaBeanDemo.java
/opt/lab/beanutils/proj/src/main/java/com/example/beanutils/MapBeanDemo.java
/opt/lab/beanutils/proj/src/main/java/com/example/beanutils/Model.java
/opt/lab/beanutils/proj/src/main/java/com/example/beanutils/NestedDemo.java

4.2 核查依赖树

# mvn dependency:tree 2>&1 | sed -n '/maven-dependency-plugin/,/BUILD SUCCESS/p' | head -9
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ beanutils-lab ---
[INFO] com.example:beanutils-lab:jar:1.0.0
[INFO] \- commons-beanutils:commons-beanutils:jar:1.11.0:compile
[INFO]    +- commons-logging:commons-logging:jar:1.3.5:compile
[INFO]    \- commons-collections:commons-collections:jar:3.2.2:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS

依赖树与官方 pom 声明一致:commons-beanutils 1.11.0 下挂 commons-logging 1.3.5 与 commons-collections 3.2.2 两个 compile 依赖。这正是方案 B 手动安装时必须一并放入 classpath 的两个 jar。

4.3 编译

# mvn -q compile
# ls target/classes/com/example/beanutils/
ConverterDemo$Form.class
ConverterDemo.class
CopyDemo$Form.class
CopyDemo.class
DynaBeanDemo.class
MapBeanDemo.class
Model$Dept.class
Model$Employee.class
Model$Manager.class
Model.class
NestedDemo.class

mvn -q 静默模式编译成功时无输出,退出码 0;target/classes 下出现全部字节码文件即编译完成。

五、方案 B:官方发行包手动接入

适合无法使用 Maven 的环境:从官方站取发行包,自行补齐依赖后用 javac/java -cp 直跑。

5.1 下载发行包并校验

# mkdir -p /opt/lab/beanutils/dist && cd /opt/lab/beanutils/dist
# curl -sSO https://downloads.apache.org/commons/beanutils/binaries/commons-beanutils-1.11.0-bin.tar.gz
# curl -sSO https://downloads.apache.org/commons/beanutils/binaries/commons-beanutils-1.11.0-bin.tar.gz.sha512
# cat commons-beanutils-1.11.0-bin.tar.gz.sha512
c1c0e71f526db64fc7aa9934f2910eedea5e575909edb3de39566e9a27b300e28826f6997b23338ef93dfee34d220077ba8669459640bddf5619ca0bb740d8ba
# sha512sum commons-beanutils-1.11.0-bin.tar.gz
c1c0e71f526db64fc7aa9934f2910eedea5e575909edb3de39566e9a27b300e28826f6997b23338ef93dfee34d220077ba8669459640bddf5619ca0bb740d8ba  commons-beanutils-1.11.0-bin.tar.gz

sha512sum 输出与官方 .sha512 文件逐字一致,完整性校验通过。

5.2 解包与内容清点

# tar -xzf commons-beanutils-1.11.0-bin.tar.gz
# ls -l commons-beanutils-1.11.0/
total 2724
-rw-r--r-- 1 root root   11359 May 25  2025 LICENSE.txt
-rw-r--r-- 1 root root     179 May 25  2025 NOTICE.txt
-rw-r--r-- 1 root root   21837 May 25  2025 RELEASE-NOTES.txt
drwxr-xr-x 7 root root    4096 May 25  2025 apidocs
-rw-r--r-- 1 root root 1449634 May 25  2025 commons-beanutils-1.11.0-javadoc.jar
-rw-r--r-- 1 root root  303875 May 25  2025 commons-beanutils-1.11.0-sources.jar
-rw-r--r-- 1 root root  298782 May 25  2025 commons-beanutils-1.11.0-test-sources.jar
-rw-r--r-- 1 root root  435374 May 25  2025 commons-beanutils-1.11.0-tests.jar
-rw-r--r-- 1 root root  246806 May 25  2025 commons-beanutils-1.11.0.jar

关键观察:1.11.0 发行包内只有主 jar 与 javadoc/sources/tests 附属包,没有 lib/ 目录,运行期依赖需要另行下载,这就是 5.3 存在的原因。

5.3 从中央仓库补齐运行期依赖

按 4.2 依赖树的版本号取两个依赖 jar:

# mkdir -p /opt/lab/beanutils/manual/lib && cd /opt/lab/beanutils/manual
# cp /opt/lab/beanutils/dist/commons-beanutils-1.11.0/commons-beanutils-1.11.0.jar lib/
# curl -sSO https://repo.maven.apache.org/maven2/commons-logging/commons-logging/1.3.5/commons-logging-1.3.5.jar
# curl -sSO https://repo.maven.apache.org/maven2/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2.jar
# mv commons-logging-1.3.5.jar commons-collections-3.2.2.jar lib/
# ls -l lib/
total 896
-rw-r--r-- 1 root root 246806 commons-beanutils-1.11.0.jar
-rw-r--r-- 1 root root 588337 commons-collections-3.2.2.jar
-rw-r--r-- 1 root root  73737 commons-logging-1.3.5.jar

三个 jar 齐备:主 jar 246806 字节、collections 588337 字节、logging 73737 字节。

5.4 编译与运行

把示例源码复制过来编译(源码与方案 A 相同,-encoding UTF-8 必须带上):

# cp -r /opt/lab/beanutils/proj/src .
# javac -encoding UTF-8 -cp lib/commons-beanutils-1.11.0.jar -d out $(find src -name "*.java")
# ls out/com/example/beanutils/ | head -3
ConverterDemo$Form.class
ConverterDemo.class
CopyDemo.class

先做一个反例:classpath 只给主 jar,运行即报依赖缺失:

# java -cp out:lib/commons-beanutils-1.11.0.jar com.example.beanutils.NestedDemo
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
        at org.apache.commons.beanutils.ConvertUtilsBean.<init>(ConvertUtilsBean.java:154)
        at org.apache.commons.beanutils.BeanUtilsBean.<init>(BeanUtilsBean.java:113)
        at org.apache.commons.beanutils.BeanUtilsBean$1.initialValue(BeanUtilsBean.java:55)

这是手动安装最常见的坑:BeanUtils 初始化时就要用 commons-logging。补齐后运行:

# java -cp out:lib/commons-beanutils-1.11.0.jar:lib/commons-logging-1.3.5.jar:lib/commons-collections-3.2.2.jar com.example.beanutils.NestedDemo
读 dept.deptName = null
读 dept.manager.name = null
写后读 dept.deptName = 平台架构部
写后读 dept.manager.title = 高级经理
整对象核对 = 李四 @ 平台架构部

输出正常,方案 B 接入完成。中文输出依赖 UTF-8 locale,若出现问号见 FAQ Q2。

六、方案对比与选型建议

维度方案 A:Maven 依赖方案 B:发行包手动安装
依赖管理自动拉取 logging/collections 两个传递依赖必须按依赖树手动补齐三个 jar
版本升级改 pom 版本号重新构建即可重新下载发行包并核对 sha512
适用场景常规工程、CI 流水线无外网构建机、只读运维环境
出错概率低(依赖树可核查)高(漏 jar 直接 NoClassDefFoundError)
离线友好需预置本地仓库天然离线

选型建议:优先方案 A,依赖树一行命令即可核查;只有目标机器完全无法使用 Maven 时选方案 B,且务必同时放主 jar、commons-logging、commons-collections 三个 jar。

七、最小验证

无论哪种方案,用同一段「嵌套属性读写」代码验证安装是否可用。NestedDemo.java 全文:

package com.example.beanutils;

import org.apache.commons.beanutils.PropertyUtils;

/** 示例:PropertyUtils 跨层级嵌套属性读写 */
public class NestedDemo {
    public static void main(String[] args) throws Exception {
        Model.Employee emp = new Model.Employee();
        emp.setEmpName("张三");
        emp.setAge(30);

        String deptName = (String) PropertyUtils.getProperty(emp, "dept.deptName");
        String mgrName = (String) PropertyUtils.getProperty(emp, "dept.manager.name");
        System.out.println("读 dept.deptName = " + deptName);
        System.out.println("读 dept.manager.name = " + mgrName);

        PropertyUtils.setProperty(emp, "dept.deptName", "平台架构部");
        PropertyUtils.setProperty(emp, "dept.manager.name", "李四");
        PropertyUtils.setProperty(emp, "dept.manager.title", "高级经理");

        System.out.println("写后读 dept.deptName = " + PropertyUtils.getProperty(emp, "dept.deptName"));
        System.out.println("写后读 dept.manager.title = " + PropertyUtils.getProperty(emp, "dept.manager.title"));
        System.out.println("整对象核对 = " + emp.getDept().getManager().getName() + " @ " + emp.getDept().getDeptName());
    }
}

Maven 方案直接运行:

# cd /opt/lab/beanutils/proj
# mvn -q compile exec:java -Dexec.mainClass=com.example.beanutils.NestedDemo
读 dept.deptName = null
读 dept.manager.name = null
写后读 dept.deptName = 平台架构部
写后读 dept.manager.title = 高级经理
整对象核对 = 李四 @ 平台架构部

初始为空的嵌套字段读出 null 不抛异常;写入后逐层 setter 被正确调用,三条核对输出与预期一致,安装验证通过。

八、FAQ

Q1:运行时报 NoClassDefFoundError: org/apache/commons/logging/LogFactory 怎么办?

这是手动安装时 classpath 缺 commons-logging 导致。实测复现与解法:把 commons-logging-1.3.5.jar 与 commons-collections-3.2.2.jar 一并加入 -cp,即 5.4 的三个 jar 写法;Maven 方案则由依赖树自动带上,无此问题。

Q2:程序里输出的中文变成了问号?

本机默认 locale 是 POSIX(mvn -v 显示 platform encoding: ANSI_X3.4-1968),JVM 按 ASCII 编码输出。实测在执行命令前加 export LANG=C.UTF-8,JVM 即按 UTF-8 输出,中文恢复正常;编译源码时同时保留 -encoding UTF-8(Maven 已由 project.build.sourceEncoding 覆盖)。

Q3:不固定插件版本时 Maven 用了很旧的编译插件?

实测在未显式声明版本的工程里,首次构建报错信息中出现 maven-compiler-plugin:3.1:compile,该老插件对高版本 JDK 支持差。解法是在 pom 的 <build><plugins> 中显式固定 maven-compiler-plugin 3.11.0(见 4.1),构建行为在 Maven 3.6.3 上稳定可复现。

Q4:1.11.0 与 2.0.0-M2 该选哪个?

生产选 1.11.0:它与 1.x 全系 API 兼容、Maven 坐标 commons-beanutils:commons-beanutils 不变。2.0.0-M2 属于新坐标 commons-beanutils2 的里程碑预览,包名与坐标都会变,仅适合前瞻性验证,不要引入生产依赖。

九、卸载

按接入方式分别清理。方案 A 的工程与本地仓库缓存:

# rm -rf /opt/lab/beanutils/proj
# rm -rf ~/.m2/repository/commons-beanutils

方案 B 的发行包与依赖目录:

# rm -rf /opt/lab/beanutils/dist /opt/lab/beanutils/manual

卸载工具链本身(先 Maven 后 JDK,并验证卸载结果):

# apt-get purge -y maven
Removing maven (3.6.3-5) ...
Purging configuration files for maven (3.6.3-5) ...
# mvn -v
bash: line 1: mvn: command not found
# apt-get purge -y openjdk-17-jdk openjdk-17-jre
Removing openjdk-17-jdk:amd64 (17.0.20.1+1-1~22.04) ...
Removing openjdk-17-jre:amd64 (17.0.20.1+1-1~22.04) ...

mvn -v 报 command not found 证明卸载生效。若还需恢复环境,反向安装即可:

# apt-get install -y openjdk-17-jdk maven

恢复后实测 java -version 回到 17.0.20.1、mvn -v 回到 Apache Maven 3.6.3。

十、参考链接

  1. Apache Commons BeanUtils 官方主页:https://commons.apache.org/proper/commons-beanutils/
  2. 官方下载目录(binaries 与 sha512):https://downloads.apache.org/commons/beanutils/
  3. Maven 中央仓库坐标页:https://repo.maven.apache.org/maven2/commons-beanutils/commons-beanutils/
  4. 官方用户指南:https://commons.apache.org/proper/commons-beanutils/userguide.html
  5. Apache Maven 官方文档:https://maven.apache.org/guides/