Apache Commons BeanUtils 常用 CLI 命令与工具详解

Commons BeanUtils 无自带命令行工具,本篇实测其命令链路:Maven 的 compile、exec:java、dependency:tree,JDK 的 jar、javap、java -cp,及发行包校验解包,附报错排查。

Apache Commons BeanUtilsApache Commons BeanUtils2026/10/13

Apache Commons BeanUtils 常用 CLI 命令与工具详解

目标:Commons BeanUtils 是纯 Java 库,本身不提供任何命令行可执行程序,本篇实测整理围绕它展开日常工作的完整命令链路——Maven 工具链(compile、exec:java、dependency:tree)、JDK 自带工具(jar、javap、java -cp)与发行包处理命令(curl、sha512sum、tar),全部命令在 Ubuntu 22.04(OpenJDK 17.0.20.1、Maven 3.6.3)与 CentOS Linux 8(OpenJDK 17.0.1、Maven 3.10.0)实测通过。

一、环境信息

本篇所有命令与回显均在以下环境实测采集:

  • 操作系统:Ubuntu 22.04.5 LTS(x86_64,内核 6.8.0-138-generic)为主,CentOS Linux 8 做交叉验证
  • JDK:OpenJDK 17.0.20.1(Ubuntu)/ OpenJDK 17.0.1(CentOS 8)
  • 构建工具:Apache Maven 3.6.3(Ubuntu)/ Apache Maven 3.10.0(CentOS 8)
  • 组件版本:Apache Commons BeanUtils 1.11.0 及其依赖 commons-logging 1.3.5、commons-collections 3.2.2
  • 实验目录:/opt/lab/beanutils(Maven 工程 proj、手动目录 manual、发行包目录 dist)
  • 执行用户:root

命令分三组:Maven 工具链负责依赖与构建执行;JDK 自带工具负责字节码观察与手动运行;发行包命令负责获取与校验。三组命令可独立使用,也可串成完整工作流。

二、Maven 工具链命令

2.1 环境自检:mvn -v

# 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"

重点看两行:Java version 确认 Maven 用的 JDK 与预期一致;platform encoding: ANSI_X3.4-1968 提示未启用 UTF-8 locale,运行含中文输出的示例前先 export LANG=C.UTF-8。

2.2 编译:mvn compile

# cd /opt/lab/beanutils/proj
# mvn -q compile
# echo $?
0

-q 静默模式下编译成功无输出,用退出码 0 确认;产物落在 target/classes。去掉 -q 可看到 [INFO] BUILD SUCCESS 的完整过程日志。

2.3 直接运行示例:mvn exec:java

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

五个示例类的运行命令汇总(回显详见第五篇快速入门,此处不重复):

# mvn -q compile exec:java -Dexec.mainClass=com.example.beanutils.CopyDemo
# mvn -q compile exec:java -Dexec.mainClass=com.example.beanutils.ConverterDemo
# mvn -q compile exec:java -Dexec.mainClass=com.example.beanutils.DynaBeanDemo
# mvn -q compile exec:java -Dexec.mainClass=com.example.beanutils.MapBeanDemo

-Dexec.mainClass 传完整类名;工程已固定 exec-maven-plugin 3.1.0,无需额外写 <mainClass> 配置即可逐类运行。

2.4 依赖核查:mvn dependency:tree

# 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

这条命令是手动安装(方案 B)的「依赖清单生成器」:树里出现的每个坐标都要在 -cp 里给到对应 jar。

三、JDK 自带工具命令

3.1 查看 jar 内容:jar tf

# jar tf dist/commons-beanutils-1.11.0/commons-beanutils-1.11.0.jar | head -6
META-INF/
META-INF/MANIFEST.MF
org/
org/apache/
org/apache/commons/
org/apache/commons/beanutils/
# jar tf dist/commons-beanutils-1.11.0/commons-beanutils-1.11.0.jar | grep -c "\.class$"
135

主 jar 内共 135 个 class 文件,包根为 org/apache/commons/beanutils。排查「类是否存在」「包名是否正确」时用它最快。

3.2 反汇编 API 签名:javap

# javap -cp dist/commons-beanutils-1.11.0/commons-beanutils-1.11.0.jar org.apache.commons.beanutils.BeanUtils | head -12
Compiled from "BeanUtils.java"
public class org.apache.commons.beanutils.BeanUtils {
  public static java.lang.Object cloneBean(java.lang.Object) throws java.lang.IllegalAccessException, java.lang.InstantiationException, java.lang.reflect.InvocationTargetException, java.lang.NoSuchMethodException;
  public static void copyProperties(java.lang.Object, java.lang.Object) throws java.lang.IllegalAccessException, java.lang.reflect.InvocationTargetException;
  public static void copyProperty(java.lang.Object, java.lang.String, java.lang.Object) throws java.lang.IllegalAccessException, java.lang.reflect.InvocationTargetException;
  public static <K, V> java.util.Map<K, V> createCache();
  public static java.util.Map<java.lang.String, java.lang.String> describe(java.lang.Object) throws java.lang.IllegalAccessException, java.lang.reflect.InvocationTargetException, java.lang.NoSuchMethodException;
  public static java.lang.String[] getArrayProperty(java.lang.Object, java.lang.String) throws java.lang.IllegalAccessException, java.lang.reflect.InvocationTargetException, java.lang.NoSuchMethodException;
  public static boolean getCacheFast(java.util.Map<?, ?>);
  public static int getDebug();
  public static java.lang.String getIndexedProperty(java.lang.Object, java.lang.String) throws java.lang.IllegalAccessException, java.lang.reflect.InvocationTargetException, java.lang.NoSuchMethodException;
  public static java.lang.String getIndexedProperty(java.lang.Object, java.lang.String, int) throws java.lang.IllegalAccessException, java.lang.reflect.InvocationTargetException, java.lang.NoSuchMethodException;

签名能直接回答参数顺序类疑问:copyProperties(java.lang.Object, java.lang.Object) 不带泛型名,需查官方文档确认首参为 dest;describe 返回 Map<String, String>,值全为字符串。javap -v 加 -v 还能看到 major version: 52 的字节码版本。

3.3 手动编译运行:javac 与 java -cp

编译(encoding 必须显式给 UTF-8):

# cd /opt/lab/beanutils/manual
# javac -encoding UTF-8 -cp lib/commons-beanutils-1.11.0.jar -d out $(find src -name "*.java")

缺依赖的反例(只放主 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)

三 jar 齐备的正确运行:

# 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 = 高级经理
整对象核对 = 李四 @ 平台架构部

-cp 用冒号分隔(Linux 惯例),顺序无关;缺哪个 jar 报哪个 NoClassDefFoundError,报错栈首行类名就是线索。

四、发行包处理命令

4.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

curl -sS -O 静默下载并保留远端文件名;-S 保证出错时仍打印错误。两段 sha512 逐字一致才算校验通过。

4.2 解包与清点

# tar -xzf commons-beanutils-1.11.0-bin.tar.gz
# tar -tzf commons-beanutils-1.11.0-bin.tar.gz | head -5
commons-beanutils-1.11.0/LICENSE.txt
commons-beanutils-1.11.0/NOTICE.txt
commons-beanutils-1.11.0/RELEASE-NOTES.txt
commons-beanutils-1.11.0/commons-beanutils-1.11.0-javadoc.jar
commons-beanutils-1.11.0/commons-beanutils-1.11.0-sources.jar
# ls -l commons-beanutils-1.11.0/ | head -6
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

tar -tzf 先列清单不解包,适合确认包内结构;1.11.0 发行包只有主 jar 与附属 jar,没有 lib/ 依赖目录,依赖需另取。

4.3 补依赖 jar

# cd /opt/lab/beanutils/manual
# 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

依赖 URL 的版本号以 2.4 依赖树输出为准,三个 jar 文件大小与实测一致即取材正确。

五、命令速查表

场景命令关键参数
构建工具自检mvn -v看 Java version 与 platform encoding
编译工程mvn -q compile-q 静默,退出码判成败
运行示例mvn -q compile exec:java -Dexec.mainClass=完整类名mainClass 传全限定名
依赖核查mvn dependency:tree树中坐标即 classpath 清单
看 jar 内容jar tf commons-beanutils-1.11.0.jar配 grep -c "\.class$" 数类
反汇编签名javap -cp commons-beanutils-1.11.0.jar 全限定类名-v 可看 major version
手动编译javac -encoding UTF-8 -cp 主jar -d out $(find src -name "*.java")encoding 必给
手动运行java -cp out:主jar:logging:collections 类名冒号分隔
下载curl -sSO URL-sS 静默留错
校验sha512sum 文件与官方 .sha512 比对
解包/清单tar -xzf / tar -tzf-z 处理 gz

六、FAQ

Q1:exec:java 报找不到主类?

-Dexec.mainClass 必须是全限定名(含包名),并确认 mvn compile 已通过;类名大小写与文件名一致,如 com.example.beanutils.NestedDemo。

Q2:示例中文输出变问号?

系统默认 POSIX locale 所致,先 export LANG=C.UTF-8 再运行;手动 javac 时同时保留 -encoding UTF-8,两个环节缺一不可。

Q3:手动运行报 NoClassDefFoundError: org/apache/commons/logging/LogFactory?

classpath 缺依赖 jar。用 mvn dependency:tree 的输出核对三 jar(主 jar、commons-logging、commons-collections)是否全部就位,并确认 -cp 冒号分隔写法正确。

Q4:javap 报「找不到类」?

-cp 指向 jar 文件本身(不是目录),类名用全限定名。例如 javap -cp lib/commons-beanutils-1.11.0.jar org.apache.commons.beanutils.BeanUtils;jar 路径错了会当成目录找不到。

七、参考链接

  1. Apache Commons BeanUtils 官方主页:https://commons.apache.org/proper/commons-beanutils/
  2. 官方下载目录:https://downloads.apache.org/commons/beanutils/
  3. Maven 中央仓库坐标页:https://repo.maven.apache.org/maven2/commons-beanutils/commons-beanutils/
  4. Apache Maven 官方文档:https://maven.apache.org/guides/
  5. exec-maven-plugin 用法:https://www.mojohaus.org/exec-maven-plugin/