Ubuntu 22.04 安装 Apache Commons Math 指南
在 Ubuntu 22.04 上从零搭建 Apache Commons Math 3.6.1 使用环境,覆盖版本选型与断代事实、Maven 在线依赖与官方二进制包两套方案、编码与 JVM 运行要点、多版本共存与常见问题排查,全部命令与回显均已实测。
Ubuntu 22.04 安装 Apache Commons Math 指南
目标:在 Ubuntu 22.04 上从零搭建 Apache Commons Math 3.6.1 的使用环境,完成 JDK 17 + Maven 环境准备、Maven 在线依赖与官方二进制包两种引入方式、真实统计与线性代数运算验证。以下全部命令与回显均已在 Ubuntu 22.04(x86_64)实测通过。
一、环境信息
本节先固定本次实测所用软硬件基线,便于读者逐项对照复现。
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- JDK:OpenJDK 17.0.20.1(
java -version实测) - 构建工具:Apache Maven 3.6.3(系统包仓库默认版本)
- 目标库:Apache Commons Math 3.6.1(
org.apache.commons:commons-math3:3.6.1) - 依赖来源:
https://downloads.apache.org/commons/math/、https://repo1.maven.org/maven2/(网络直连可达) - Maven 示例工程目录:
/opt/math-demo - 官方二进制包解压目录:
/opt/math-jars
先确认系统版本与架构:
cat /etc/os-release | head -3
uname -m
输出:
PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
x86_64
二、前置条件
在开始安装前,请确认以下条件满足,否则后续步骤会因权限或网络问题中断。本节说明每项前置条件的作用与验证方法。
- root 权限或 sudo:安装 JDK、Maven 需要写入系统目录(
/usr/lib/jvm、/usr/share/maven)。 - 网络可达:需要访问
downloads.apache.org(官方二进制包)与repo1.maven.org(Maven 中央仓库)。 - 磁盘空间:官方二进制包 18,577,952 字节(约 18 MB),加上本地 Maven 仓库缓存建议预留 ≥ 300 MB。
- 架构无关:Commons Math 为纯 Java 库,无本地原生依赖,跨架构可用。
验证网络连通性(该库的下载目录与 Maven 中央仓库各探测一次):
curl -sI https://downloads.apache.org/commons/math/ | head -1
curl -sI https://repo1.maven.org/maven2/org/apache/commons/commons-math3/ | head -1
输出:
HTTP/1.1 200 OK
HTTP/1.1 200 OK
⚠️ 注意:Commons Math 是纯类库(无独立进程),不会注册系统服务,"安装"的实质是把 jar 放进工程或 classpath。若内网无法直连上述域名,需按企业代理配置放行,否则 Maven 依赖与官方包均无法获取。本文实测环境为直连,下载大文件失败的代理处理见 5.2 节。
三、版本选型说明
Apache Commons Math 是 Apache 基金会的数学与统计计算库。安装前必须先弄清它的版本断代事实,避免版本选型失误。本节给出 Maven Central 与官方下载目录的实测版本清单。
3.1 版本现状:稳定线断代约 10 年,新一代长期停留 beta
查询 Maven Central 上 commons-math3 的全量版本元数据:
curl -s https://repo1.maven.org/maven2/org/apache/commons/commons-math3/maven-metadata.xml
输出:
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<versioning>
<latest>3.6.1</latest>
<release>3.6.1</release>
<versions>
<version>3.0</version>
<version>3.1</version>
<version>3.1.1</version>
<version>3.2</version>
<version>3.3</version>
<version>3.4</version>
<version>3.4.1</version>
<version>3.5</version>
<version>3.6</version>
<version>3.6.1</version>
</versions>
<lastUpdated>20160321125613</lastUpdated>
</versioning>
</metadata>
关键结论:latest/release 均为 3.6.1,lastUpdated=20160321125613(2016-03-21),此后至今无任何新版本——稳定线已断代约 10 年(2016→2026),但 API 成熟、零传递依赖,仍是生产首选。
再查新一代 commons-math4 的模块元数据(以 commons-math4-legacy 为例):
curl -s https://repo1.maven.org/maven2/org/apache/commons/commons-math4-legacy/maven-metadata.xml
输出:
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math4-legacy</artifactId>
<versioning>
<latest>4.0-beta1</latest>
<release>4.0-beta1</release>
<versions>
<version>4.0-beta1</version>
</versions>
<lastUpdated>20221219132611</lastUpdated>
</versioning>
</metadata>
commons-math4 全部 6 个模块的查询结果结构完全一致:均只含 4.0-beta1 一个版本,lastUpdated 均为 2022-12-19,此后无更新。
官方下载目录的在架发行版(downloads.apache.org 只保留当前最新发行线):
curl -s https://downloads.apache.org/commons/math/binaries/ | grep -E "tar.gz|zip</a>"
输出:
<a href="commons-math-2.2.tar.gz">commons-math-2.2.tar.gz</a> 2013-03-03 21:07 10M
<a href="commons-math3-3.6.1-bin.tar.gz">commons-math3-3.6.1-bin.tar.gz</a> 2016-03-21 12:48 18M
<a href="commons-math3-3.6.1-bin.zip">commons-math3-3.6.1-bin.zip</a> 2016-03-21 12:48 21M
<a href="commons-math4-4.0-beta1-bin.tar.gz">commons-math4-4.0-beta1-bin.tar.gz</a> 2022-12-19 13:19 13M
<a href="commons-math4-4.0-beta1-bin.zip">commons-math4-4.0-beta1-bin.zip</a> 2022-12-19 13:19 14M
官网下载页(commons.apache.org/proper/commons-math/)把 4.0-beta1 列为最新发行版并注明 "requires Java 8+",而站点文档自身版本仍停在 4.0-SNAPSHOT——math4 处于长期 beta/半停滞状态(截至 2026-10 已约 4 年无新版本)。
3.2 版本对照与选型
| 版本线 | 最新版本 | 发布日期 | Java 要求 | 状态与建议 |
|---|---|---|---|---|
| commons-math3 | 3.6.1 | 2016-03-21 | Java 1.5+(实测字节码 major=49) | 生产环境首选;断代约 10 年但 API 稳定、零传递依赖、JDK 8/17 实测可运行 |
| commons-math4 | 4.0-beta1 | 2022-12-19 | Java 8+ | 仅建议评估迁移时试用;beta 后停滞约 4 年,官方自述 "work-in-progress" |
解读:新项目直接选 commons-math3 3.6.1;math4 是一次大规模重构(旧 API 迁入 org.apache.commons.math4.legacy.*,低层能力拆分至 Commons RNG/Numbers/Geometry/Statistics 四个新组件),至今未发布正式版。两者包名不同(org.apache.commons.math3 与 org.apache.commons.math4),可在同一工程共存,详见第八章。
3.3 commons-math4 4.0-beta1 模块清单
若需评估 math4,其 Maven Central 模块构成如下(六个模块全部只有 4.0-beta1):
| Maven artifact(groupId 均为 org.apache.commons) | 版本 | 作用 |
|---|---|---|
| commons-math4-core | 4.0-beta1 | 全新极简核心(实测仅 18 个类,AccurateMath/JdkMath 高精度数学函数) |
| commons-math4-legacy | 4.0-beta1 | 旧 API 主体(DescriptiveStatistics 等在此,包名 org.apache.commons.math4.legacy.*) |
| commons-math4-legacy-core | 4.0-beta1 | 旧核心工具(MathArrays 等,包名 org.apache.commons.math4.legacy.core) |
| commons-math4-legacy-exception | 4.0-beta1 | 旧异常体系 |
| commons-math4-neuralnet | 4.0-beta1 | 神经网络(包名 org.apache.commons.math4.neuralnet) |
| commons-math4-transform | 4.0-beta1 | 变换(傅里叶等,包名 org.apache.commons.math4.transform) |
⚠️ 注意:math4 的二进制包解压后顶层目录名为
commons-math-4.0-beta1(没有 "4" 后缀),与包名 commons-math4 不一致,写脚本时留意。
💡 技术拓展:JVM 数值计算库不止本文所用的 Apache Commons Math。常见选项对比——
库 语言/形态 特点 适用场景 Commons Math 3.6.1 Java 纯库 统计/线性代数/复数/分数/素数一站式,零传递依赖 通用数学统计工具、算法原型、教学 EJML Java 纯库 专注线性代数,矩阵运算性能与 API 现代化程度更高 以矩阵运算为主、性能敏感场景 ND4J Java 纯库 N 维数组 + 张量运算,可接原生后端(CUDA/OpenBLAS) 深度学习前处理、张量计算 ojAlgo Java 纯库 线性代数 + 优化/金融数学,大矩阵性能好 运筹优化、量化计算 本文选用 commons-math3 3.6.1:它是唯一同时覆盖统计推断与线性代数、且零传递依赖的选项,引入成本最低;若业务只做矩阵乘法/分解且追求吞吐,可另评估 EJML。
四、在线安装方案(A:Maven 依赖引入)
官方推荐方式:通过 Maven 引入 commons-math3:3.6.1,由构建工具自动下载并管理 jar。适合可联网的开发/构建环境。
4.1 方案说明与适用场景
本方案在系统安装 JDK 17 与 Maven,再用一个最小 Maven 工程引入 commons-math3:3.6.1,最后编译运行一个真实统计程序完成验证。适合持续集成、可访问中央仓库的场景。
4.2 安装 JDK 17 与 Maven
如系统尚未安装 JDK 17 与 Maven,Ubuntu 22.04 可执行:
apt-get update -qq
DEBIAN_FRONTEND=noninteractive apt-get install -y openjdk-17-jdk maven
⚠️ 注意:本文实测环境两者均已预装,以上命令为标准安装方式,安装后以下方验证命令的实测回显为准。
验证 JDK 与 Maven 生效:
java -version
mvn -v | head -3
输出:
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)
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.3 创建 Maven 工程并引入依赖
创建工程目录:
mkdir -p /opt/math-demo/src/main/java/demo
/opt/math-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>demo</groupId>
<artifactId>math-demo</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>17</maven.compiler.release>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.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>
逐项说明:
project.build.sourceEncoding=UTF-8:源码编码。示例代码含中文注释/字符串,必须显式声明,否则按平台默认编码(ANSI_X3.4-1968/POSIX)编译会报unmappable character。maven.compiler.release=17:用 JDK 17 语义产出字节码。commons-math3 自身是 Java 5 字节码(major=49),可被任何更高版本 JDK 运行,工程侧用高版本编译互不影响。dependencies:仅声明commons-math3:3.6.1一项。该库零传递依赖(4.5 节依赖树实测验证),无需再补任何 jar。maven-compiler-plugin显式固定 3.11.0:Maven 3.6.3 默认绑定的 compiler 插件是 3.1,不认识maven.compiler.release属性,会退回 source/target=1.5 并被 JDK 17 的 javac 拒绝。踩坑实录见 9.1 节(Q1)。
4.4 编写最小验证程序
/opt/math-demo/src/main/java/MathCheck.java 全文:
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
public class MathCheck {
public static void main(String[] args) {
DescriptiveStatistics ds = new DescriptiveStatistics();
for (double v : new double[] {9, 2, 5, 4, 12, 7, 8, 11, 9, 3}) {
ds.addValue(v);
}
System.out.println("N=" + ds.getN()
+ " mean=" + ds.getMean()
+ " sd=" + ds.getStandardDeviation()
+ " p50=" + ds.getPercentile(50));
System.out.println("commons-math3 OK");
}
}
说明:用 commons-math3 的描述统计类 DescriptiveStatistics 对 10 个测量值计算样本数、均值、标准差与中位数,是库最核心的统计入口。
4.5 编译与运行验证
首次编译(安静模式,成功时无任何输出):
cd /opt/math-demo && mvn -q compile
echo "EXIT=$?"
输出:
EXIT=0
再跑一次完整编译,查看构建细节:
mvn clean compile 2>&1 | tail -14
输出:
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ math-demo ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /opt/math-demo/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.11.0:compile (default-compile) @ math-demo ---
[INFO] Changes detected - recompiling the module! :source
[INFO] Compiling 1 source file with javac [debug release 17] to target/classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.876 s
[INFO] Finished at: 2026-10-14T15:29:51Z
验证依赖树(确认零传递依赖):
mvn dependency:tree 2>&1 | grep -A 8 "maven-dependency-plugin:2.8:tree" | head -14
输出:
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ math-demo ---
[INFO] demo:math-demo:jar:1.0.0
[INFO] \- org.apache.commons:commons-math3:jar:3.6.1:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.777 s
[INFO] Finished at: 2026-10-14T15:15:02Z
[INFO] ------------------------------------------------------------------------
解读:依赖树中除工程自身外只有 commons-math3:3.6.1 一个节点,零传递依赖,不会引入任何版本冲突。
运行验证程序(classpath 由 target/classes 与本地仓库中的 math3 jar 组成):
M3=~/.m2/repository/org/apache/commons/commons-math3/3.6.1/commons-math3-3.6.1.jar
java -Dfile.encoding=UTF-8 -cp target/classes:$M3 MathCheck
输出:
N=10 mean=7.0 sd=3.39934634239519 p50=7.5
commons-math3 OK
验证点:均值 7.0(10 个数总和 70)、中位数 7.5(排序后第 5、6 个数 7 与 8 的平均),结果正确,说明依赖已正确引入且可运行。-Dfile.encoding=UTF-8 用于 POSIX locale 下中文输出不乱码(见 9.3 节 Q3)。
五、离线安装方案(B:官方二进制包)
适合内网隔离、无法访问中央仓库的环境。官方 commons-math3-3.6.1-bin.tar.gz 内含主 jar 与 javadoc/sources,且零传递依赖,解压即用,无需补任何第三方 jar。
5.1 方案说明与适用场景
本方案从官方下载目录获取二进制包,做哈希校验后解压,再用 javac/java -cp 直接编译运行验证。全程不依赖 Maven。
5.2 下载与校验
创建存放目录并下载(本文实测环境直连 downloads.apache.org 速度仅约 46KB/s,且大文件直连曾出现下载不完整,因此直接走本地代理下载;无代理环境可去掉 -x 参数直连,下载后务必校验):
mkdir -p /opt/math-jars
cd /opt/math-jars
curl -sLO -x http://192.168.1.62:7897 https://downloads.apache.org/commons/math/binaries/commons-math3-3.6.1-bin.tar.gz
下载官方 sha256 校验文件并核对(官方只提供 sha1/sha256/asc,没有 sha512 校验文件):
curl -sLO -x http://192.168.1.62:7897 https://downloads.apache.org/commons/math/binaries/commons-math3-3.6.1-bin.tar.gz.sha256
cat commons-math3-3.6.1-bin.tar.gz.sha256
sha256sum commons-math3-3.6.1-bin.tar.gz
输出:
7fc2750a5759b2cdb951ede83779f39c195705273ab010d42356ec676fe99674 *./math/binaries/commons-math3-3.6.1-bin.tar.gz
7fc2750a5759b2cdb951ede83779f39c195705273ab010d42356ec676fe99674 commons-math3-3.6.1-bin.tar.gz
两行哈希一致,包完整可信。再确认包大小与 gzip 完整性,并计算 sha512 备档(本地计算值,非官方提供):
ls -l commons-math3-3.6.1-bin.tar.gz
gzip -t commons-math3-3.6.1-bin.tar.gz && echo "gzip OK"
sha512sum commons-math3-3.6.1-bin.tar.gz
输出:
-rw-r--r-- 1 root root 18577952 Oct 14 15:24 commons-math3-3.6.1-bin.tar.gz
gzip OK
cd69bcaf6e4b72ed24d6f9c16f5fcc5e3ae832b2cc1ea7dbe6d189936cf4e408913be60db82e43c5517164379651040cb9f45d38dde2854ac2712e9c7aff9afd commons-math3-3.6.1-bin.tar.gz
验证点:包大小 18,577,952 字节,gzip -t 通过,sha256 与官方一致。直连下载不完整的排障过程见 9.4 节(Q4)。
5.3 解压与目录结构
解压并查看内容:
tar xzf commons-math3-3.6.1-bin.tar.gz
ls commons-math3-3.6.1/
输出:
LICENSE.txt
NOTICE.txt
RELEASE-NOTES.txt
commons-math3-3.6.1-javadoc.jar
commons-math3-3.6.1-sources.jar
commons-math3-3.6.1-test-sources.jar
commons-math3-3.6.1-tests.jar
commons-math3-3.6.1-tools.jar
commons-math3-3.6.1.jar
docs
主 jar 内部结构与条目数:
cd commons-math3-3.6.1
jar tf commons-math3-3.6.1.jar | head -12
输出:
META-INF/
META-INF/MANIFEST.MF
org/
org/apache/
org/apache/commons/
org/apache/commons/math3/
org/apache/commons/math3/ml/
org/apache/commons/math3/ml/neuralnet/
org/apache/commons/math3/ml/neuralnet/twod/
org/apache/commons/math3/ml/neuralnet/twod/util/
org/apache/commons/math3/ml/neuralnet/oned/
org/apache/commons/math3/ml/neuralnet/sofm/
jar tf commons-math3-3.6.1.jar | wc -l
输出:
1402
查看 MANIFEST 关键属性(确认最低 Java 版本与构建信息;本环境无 unzip,用 jar xf 解出后查看):
mkdir -p /tmp/m3-meta && cd /tmp/m3-meta && jar xf /opt/math-jars/commons-math3-3.6.1/commons-math3-3.6.1.jar META-INF/MANIFEST.MF && cat META-INF/MANIFEST.MF
输出:
Implementation-Title: Apache Commons Math
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.5))"
X-Compile-Target-JDK: 1.5
X-Compile-Source-JDK: 1.5
Implementation-Version: 3.6.1
Build-Jdk: 1.7.0_95
Bundle-SymbolicName: org.apache.commons.math3
Implementation-Build: 16abfe5de688cc52fb0396e0609cb33044b15653; 2016-03-17 13:30:43-0400
解读:MANIFEST 与 Maven Central 的 pom 一致声明最低 Java 1.5(X-Compile-Target-JDK: 1.5)。再用 javap 直接验证 class 文件字节码版本:
M3=~/.m2/repository/org/apache/commons/commons-math3/3.6.1/commons-math3-3.6.1.jar
javap -v -cp $M3 org.apache.commons.math3.stat.descriptive.DescriptiveStatistics 2>/dev/null | grep -E "major|minor" | head -2
输出:
minor version: 0
major version: 49
解读:major=49 即 Java 5 字节码,与 pom 声明的 maven.compiler.source/target=1.5 完全一致——该 jar 可被 JDK 5 及以上任何运行时加载,高版本 JDK 运行无兼容问题。
5.4 手动编译运行验证
复用 4.4 节的 MathCheck.java,把源码放到 /opt/math-jars/check-src/,直接以官方 jar 作为 classpath 编译并运行:
cd /opt/math-jars
mkdir -p check-src check-classes
cp /opt/math-demo/src/main/java/MathCheck.java check-src/
javac -encoding UTF-8 -cp commons-math3-3.6.1/commons-math3-3.6.1.jar -d check-classes check-src/MathCheck.java
echo "JAVAC_EXIT=$?"
java -Dfile.encoding=UTF-8 -cp check-classes:commons-math3-3.6.1/commons-math3-3.6.1.jar MathCheck
输出:
JAVAC_EXIT=0
N=10 mean=7.0 sd=3.39934634239519 p50=7.5
commons-math3 OK
验证点:结果与方案 A 完全一致。说明不依赖 Maven、纯 jar 直跑同样可用。-encoding UTF-8 用于源码含中文时避免 unmappable character 报错。
六、方案对比与选择建议
两种方案各有取舍,本节汇总关键差异并给出选型建议。
| 维度 | 方案 A:Maven 依赖 | 方案 B:官方二进制包 |
|---|---|---|
| 是否需联网 | 构建时需访问中央仓库 | 仅下载阶段需联网(可离线分发) |
| 安装方式 | 声明依赖自动下载 | 手动下载 + 校验 + 解压 |
| 依赖完整性 | 自动解析(零传递依赖,只有 math3 一个 jar) | 零传递依赖,主 jar 解压即用 |
| 附加产物 | 仅主 jar | 附带 javadoc/sources/tests jar 与 docs 目录 |
| 耗时 | 首次下载后秒级 | 下载 18 MB + 解压 |
| 适用场景 | CI/可联网开发 | 内网隔离、离线运行、查阅源码与文档 |
选择建议:可联网优先方案 A(坐标声明即用,升级只改版本号);内网隔离选方案 B(一次校验下载后可任意分发,且自带 javadoc/sources 便于离线查阅)。两方案的 MathCheck 实测输出一致,可放心互换。
七、配置说明
Commons Math 是纯类库,没有任何配置文件(不读环境变量、无 properties/yaml 配置、无服务端口)。运行期需要关注的"配置"集中在 JVM 层面与编码,本节逐项说明实测要点。
- 源码编码:Java 源码含中文注释/字符串时,
javac需带-encoding UTF-8(见 5.4 节实测),Maven 工程由project.build.sourceEncoding=UTF-8统一控制(见 4.3 节)。 - 运行时编码:POSIX/C locale 的系统上,
System.out默认输出编码为 ANSI_X3.4-1968,中文会变成问号。实测运行时加 JVM 系统属性-Dfile.encoding=UTF-8即可正常输出中文(排障见 9.3 节 Q3)。 - JVM 内存:库本身对内存无特殊要求,本文全部示例均以 JVM 默认参数运行;处理超大样本时按需自行追加
-Xms/-Xmx启动参数,无需任何第三方配置。 - JDK 版本:3.6.1 最低要求 Java 1.5(major=49 字节码实测),实测在 JDK 17.0.20.1 正常编译运行;把工程字节码降到 release 8 后由 JDK 8 运行时执行同样通过(实测过程见第 2 篇《CentOS 8 安装 Apache Commons Math 指南》4.6 节)。
- 依赖坐标:groupId 固定
org.apache.commons,artifactId 为commons-math3,版本 3.6.1;Maven 本地仓库中该 jar 为 2,213,560 字节。
八、升级、降级与多版本管理
本节说明版本变更的实际操作空间与 math3/math4 共存方法。3.x 线自 3.6.1 之后再无版本,"升级"主要指向 math4 的迁移评估;"降级"指回退 3.x 线内旧版本。
8.1 3.x 线内的版本变更
Maven Central 元数据显示 3.x 共 10 个版本(3.0 至 3.6.1,见 3.1 节)。Maven 方式改版本号即可,例如回退 3.5:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.5</version>
</dependency>
二进制包方式则从归档目录 https://archive.apache.org/dist/commons/math/binaries/ 下载对应版本包替换(该目录可回溯 commons-math 1.0(2004-12-07)以来全部历史版本)。3.x 各版本 API 高度兼容,通常无需改代码。
8.2 math3 与 math4 多版本共存
math3 与 math4 的顶层包名不同(org.apache.commons.math3 与 org.apache.commons.math4),Maven 坐标也不同,可以在同一工程、同一 classpath 共存。以下实测验证:在 /opt/math-demo/coexist-src/demo/CoexistDemo.java 写一个同时调用两代 API 的程序:
package demo;
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
public class CoexistDemo {
public static void main(String[] args) {
double[] data = {9, 2, 5, 4, 12, 7, 8, 11, 9, 3};
DescriptiveStatistics s3 = new DescriptiveStatistics();
for (double v : data) {
s3.addValue(v);
}
System.out.println("math3 class: " + s3.getClass().getName());
System.out.println("math3 N=" + s3.getN() + " mean=" + s3.getMean());
org.apache.commons.math4.legacy.stat.descriptive.DescriptiveStatistics s4 =
new org.apache.commons.math4.legacy.stat.descriptive.DescriptiveStatistics();
for (double v : data) {
s4.addValue(v);
}
System.out.println("math4 class: " + s4.getClass().getName());
System.out.println("math4 N=" + s4.getN() + " mean=" + s4.getMean());
s4.removeMostRecentValue();
System.out.println("math4 after removeMostRecentValue: N=" + s4.getN()
+ " mean=" + s4.getMean());
}
}
说明:两个同名类 DescriptiveStatistics 分属 org.apache.commons.math3.stat.descriptive 与 org.apache.commons.math4.legacy.stat.descriptive,Java 中通过全限定名区分——import 只给 math3 一份,math4 一律写全限定名。
math4 相关 jar 可直接从 Maven Central 下载(评估用,不进工程依赖),下载后与 math3 jar 一起编译运行:
cd /opt/math-demo
R=~/.m2/repository/org/apache/commons
M3=$R/commons-math3/3.6.1/commons-math3-3.6.1.jar
M4L=$R/commons-math4-legacy/4.0-beta1/commons-math4-legacy-4.0-beta1.jar
M4LC=$R/commons-math4-legacy-core/4.0-beta1/commons-math4-legacy-core-4.0-beta1.jar
M4LE=$R/commons-math4-legacy-exception/4.0-beta1/commons-math4-legacy-exception-4.0-beta1.jar
M4C=$R/commons-math4-core/4.0-beta1/commons-math4-core-4.0-beta1.jar
javac -encoding UTF-8 -cp $M3:$M4L:$M4LC:$M4LE:$M4C -d coexist-classes coexist-src/demo/CoexistDemo.java
java -Dfile.encoding=UTF-8 -cp coexist-classes:$M3:$M4L:$M4LC:$M4LE:$M4C demo.CoexistDemo
输出:
math3 class: org.apache.commons.math3.stat.descriptive.DescriptiveStatistics
math3 N=10 mean=7.0
math4 class: org.apache.commons.math4.legacy.stat.descriptive.DescriptiveStatistics
math4 N=10 mean=7.0
math4 after removeMostRecentValue: N=9 mean=7.444444444444445
验证点:两个类加载自不同包名、计算结果一致,同一 classpath 共存无冲突。移除最近一个观测值(3)后 N=9、均值 67/9=7.444…,滚动语义正确。math4 jar 的获取:可在任意 Maven 工程中声明 commons-math4-legacy 等依赖让 Maven 拉入本地仓库,或直接从 https://repo1.maven.org/maven2/org/apache/commons/commons-math4-legacy/4.0-beta1/ 下载。
8.3 jar 目录式多版本管理
离线场景可在 /opt/math-jars 下按版本建目录并存多套 jar(如 commons-math3-3.6.1/ 与 commons-math-4.0-beta1/),运行时用 -cp 显式指定所用目录中的 jar,互不干扰。
九、常见问题(FAQ)
Q1:mvn compile 报 Source option 5 is no longer supported. Use 7 or later. 怎么办?
完整现象(同时报 Target option 5 is no longer supported. Use 7 or later.):
[ERROR] Source option 5 is no longer supported. Use 7 or later.
[ERROR] Target option 5 is no longer supported. Use 7 or later.
定位:Maven 3.6.3 默认绑定的 maven-compiler-plugin 版本是 3.1,它不认识 maven.compiler.release 属性;老插件在未显式声明 source/target 时按 1.5 处理,被 JDK 17 的 javac 拒绝。解决:在 pom 的 <build><plugins> 中显式固定 maven-compiler-plugin 版本为 3.11.0(见 4.3 节 pom 全文),修复后编译日志变为 Compiling 1 source file with javac [debug release 17](见 4.5 节实测)。
Q2:mvn compile 显示 No sources to compile 但 BUILD SUCCESS,运行时报 ClassNotFoundException 怎么办?
这是源码目录放错导致的"假成功"。实测现象:把 MathCheck.java 放在工程根目录或其他非约定目录,Maven 找不到源码,输出 No sources to compile 且仍显示 BUILD SUCCESS,target/classes 里没有任何 class,运行时报 ClassNotFoundException: MathCheck。解决:源码必须放在 src/main/java/ 约定目录下(默认包类直接放 src/main/java/MathCheck.java,带包名的类按包路径逐级建目录,如 src/main/java/demo/MathDemo.java)。修复后重新 mvn compile,日志出现 Compiling 1 source file 才是真编译成功。
Q3:运行时中文输出变成 ??? 怎么办?
系统 locale 为 POSIX/C 时,JVM 默认输出编码是 ANSI_X3.4-1968(ASCII),中文字符无法映射。实测对比:不加参数运行时中文变问号,数字结果不受影响。解决:运行时追加 JVM 系统属性:
java -Dfile.encoding=UTF-8 -cp target/classes:$M3 MathCheck
输出(中文与数字均正常):
N=10 mean=7.0 sd=3.39934634239519 p50=7.5
commons-math3 OK
编译侧同理:javac 加 -encoding UTF-8,Maven 工程设 project.build.sourceEncoding=UTF-8。
Q4:直连 downloads.apache.org 下载的包解压报错怎么办?
实测现象:直连下载的 commons-math3-3.6.1-bin.tar.gz 只有 14,767,929 字节(完整应为 18,577,952),校验命令报错如下:
gzip: commons-math3-3.6.1-bin.tar.gz: unexpected end of file
tar: Unexpected EOF in archive
定位:大文件直连下载中途截断(实测直连速度仅约 46KB/s)。解决:走代理重新下载(见 5.2 节实测命令),重下后 18,577,952 字节、sha256 与官方一致、gzip -t 通过。教训:任何二进制包必须做哈希校验后再解压,仅凭 tar 不报错不能证明包完整。
Q5:官方没有 sha512 校验文件,想要 sha512 怎么办?
官方只提供 .sha1/.sha256/.asc 三种校验文件(math4 包才提供 .sha512)。对 3.6.1 做 sha512 校验只能本地计算后与可信来源比对,命令与实测值见 5.2 节(sha512sum 输出以 cd69bcaf 开头)。安全上以官方 .sha256 比对为准即可。
Q6:math3 3.6.1 的 API 和网上新资料对不上怎么办?
3.6.1(2016 年)与 math4/部分新文档存在 API 名差异,编译期最容易踩的三处实测锚点:
DescriptiveStatistics移除最近观测的方法是removeMostRecentValue()——写removeMostRecentObservation()编译报cannot find symbol(该名在 3.6.1 中不存在);DecompositionSolver.solve()只接受RealVector/RealMatrix,没有solve(double[])重载,需写solver.solve(new ArrayRealVector(new double[] {5, 9}));Fraction没有reduce()与percentageValue()——构造时已自动约分,百分数用doubleValue() * 100自行格式化。
十、卸载与清理
Commons Math 不做系统级安装,删除 jar、工程与缓存即可完全清理:
rm -rf /opt/math-demo /opt/math-jars /tmp/m3-meta
ls -d /opt/math-demo 2>/dev/null || echo "math-demo removed"
输出:
math-demo removed
Maven 方式还需清理本地仓库缓存中的 math3(或整库):
rm -rf ~/.m2/repository/org/apache/commons/commons-math3
如需同时移除 JDK 与 Maven:
DEBIAN_FRONTEND=noninteractive apt-get remove -y openjdk-17-jdk maven
⚠️ 注意:
apt-get remove仅移除软件包;本文的示例程序与 jar 均在/opt与~/.m2,按上方命令清理即可,无残留系统服务或开机项。
十一、参考链接
- Apache Commons Math 官方站点:https://commons.apache.org/proper/commons-math/
- 官方发行下载目录:https://downloads.apache.org/commons/math/
- 历史版本归档目录:https://archive.apache.org/dist/commons/math/
- Maven 中央仓库坐标页:https://repo1.maven.org/maven2/org/apache/commons/commons-math3/
- Commons Math 3.6.1 Javadoc(二进制包内含
docs/离线版):https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/