CentOS 8 安装 Apache Commons Math 指南
在 CentOS 8 上从零搭建 Apache Commons Math 3.6.1 使用环境,覆盖 JDK 8/17 并存切换、Maven 在线依赖与官方二进制包两套方案、JAVA_HOME 与 PATH 的实测差异、JDK 8 运行时兼容验证与常见问题排查,全部命令与回显均已实测。
CentOS 8 安装 Apache Commons Math 指南
目标:在 CentOS 8 上从零搭建 Apache Commons Math 3.6.1 的使用环境,完成 JDK 8/17 并存环境下的
JAVA_HOME切换、Maven 在线依赖与官方二进制包两种引入方式、真实统计与线性代数运算验证。以下全部命令与回显均已在 CentOS 8(x86_64)实测通过。
一、环境信息
本节先固定本次实测所用软硬件基线,便于读者逐项对照复现。CentOS 8 的特点是系统默认 Java 为 1.8,与手动安装的 JDK 17 并存,本文将给出两者的切换与共存方法。
- 操作系统:CentOS Linux release 8(x86_64)
- 默认 Java:OpenJDK 1.8.0_312(
java -version实测,系统 dnf 仓库自带) - 备用 JDK:java-17-openjdk 17.0.1(
/usr/lib/jvm/java-17-openjdk,包名 java-17-openjdk-17.0.1.0.12-2.el8_5.x86_64) - 构建工具:Apache Maven 3.5.4(Red Hat 构建版,系统仓库默认版本)
- 目标库: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
先确认系统版本与默认 Java、Maven 基线:
cat /etc/os-release | head -2
java -version 2>&1
mvn -v | head -3
输出:
NAME="CentOS Linux"
VERSION="8"
openjdk version "1.8.0_312"
OpenJDK Runtime Environment (build 1.8.0_312-b07)
OpenJDK 64-Bit Server VM (build 25.312-b07, mixed mode)
Apache Maven 3.5.4 (Red Hat 3.5.4-5)
Maven home: /usr/share/maven
Java version: 1.8.0_312, vendor: Red Hat, Inc., runtime: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.312.b07-2.el8_5.x86_64/jre
验证点:系统默认 java 为 1.8.0_312,且 Maven 默认也绑定 JDK 8。Commons Math 3.6.1 虽只需 Java 1.5+,但本文示例工程按 release 17 编译(更贴近新工程现实),因此需把 Maven 切到 JDK 17(见 4.2 节);只想"运行"已编译好的程序则 JDK 8 也能胜任(见 4.6 节实测)。
二、前置条件
在开始安装前,请确认以下条件满足,否则后续步骤会因权限或网络问题中断。
- 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。
- 注意多 JDK 并存:CentOS 8 同时存在 JDK 8 与 JDK 17 时,
java命令由 PATH 决定、Maven 由JAVA_HOME决定,两者互不影响(实测见 4.2 节与 9.1 节 Q1),务必分别确认。
验证网络连通性(该库的下载目录与 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。若内网无法直连上述域名,需按企业代理配置放行。下载大文件截断的代理处理见 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 在 Maven Central 有 6 个模块(core / legacy / legacy-core / legacy-exception / neuralnet / transform),实测每个模块都只发布过 4.0-beta1(2022-12-19)一个版本。以 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>
官方下载目录的在架发行版:
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
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。两者包名不同(org.apache.commons.math3 与 org.apache.commons.math4),可在同一 classpath 共存;CentOS 8 默认 JDK 8 也能直接运行 math3(major=49 字节码),只是编译新代码才需要 JDK 17。
💡 技术拓展:如果将来要从 math3 迁移到 math4,先看三张"地图"再动手——
迁移关注点 math3 3.6.1 现状 math4 4.0-beta1 去向 说明 旧 API 主体(DescriptiveStatistics、TTest 等) org.apache.commons.math3.*org.apache.commons.math4.legacy.*(commons-math4-legacy 模块)官方 RELEASE-NOTES 明确:升级主要就是改顶层包名 核心工具(MathArrays、FastMath 等) org.apache.commons.math3.util.*org.apache.commons.math4.legacy.core.*(legacy-core 模块)FastMath 更名 AccurateMath,位于 org.apache.commons.math4.legacy.core.jdkmath低层能力(随机数、数字类型、几何、统计) 混在 math3 内 已拆分到独立组件 Commons RNG / Numbers / Geometry / Statistics 迁移时需按功能改引对应新组件,不再是"一个依赖全包" 迁移决策建议:math4 至今只有 beta 且停滞约 4 年,生产迁移收益有限;若确需迁移,保持 math3 与 math4 同 classpath 过渡(包名不同不冲突),按模块逐步替换,低层功能改引 RNG/Numbers/Geometry/Statistics。
四、在线安装方案(A:Maven 依赖引入)
官方推荐方式:通过 Maven 引入 commons-math3:3.6.1,由构建工具自动下载并管理 jar。适合可联网的开发/构建环境。
4.1 方案说明与适用场景
本方案先在 JDK 8/17 并存环境中把 Maven 切到 JDK 17,再创建一个最小 Maven 工程引入 commons-math3:3.6.1,编译运行一个真实统计程序完成验证,最后额外验证 JDK 8 运行时兼容性。适合持续集成、可访问中央仓库的场景。
4.2 切换 Maven 使用 JDK 17
如系统尚未安装 JDK 17 与 Maven,CentOS 8 可执行 dnf install -y java-17-openjdk java-17-openjdk-devel maven 安装;本文实测环境三者均已就绪,安装后以下述命令与回显为准。
CentOS 8 的系统 Maven 3.5.4 通过 JAVA_HOME 决定所用的 JDK。先设置并验证 JDK 17 可用:
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk
$JAVA_HOME/bin/java -version 2>&1
输出:
openjdk version "17.0.1" 2021-10-19 LTS
OpenJDK Runtime Environment 21.9 (build 17.0.1+12-LTS)
OpenJDK 64-Bit Server VM 21.9 (build 17.0.1+12-LTS, mixed mode, sharing)
关键事实(实测):设置 JAVA_HOME 不会改变 PATH 上的 java 命令——此时 java -version 仍是 1.8.0_312。mvn 认 JAVA_HOME,java 认 PATH,两者互不影响。持久化设置方法见第七章;排障见 9.1 节 Q1。
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:源码编码。示例代码含中文注释/字符串,必须显式声明,否则按平台默认编码编译会报unmappable character。maven.compiler.release=17:用 JDK 17 语义产出字节码(要求 4.2 节的JAVA_HOME已切到 17)。commons-math3 自身是 Java 5 字节码(major=49),可被任何更高版本 JDK 运行。dependencies:仅声明commons-math3:3.6.1一项。该库零传递依赖,无需再补任何 jar。maven-compiler-plugin显式固定 3.11.0:Maven 3.5.4(Red Hat 构建版)同样默认绑定老版 compiler 插件,不认识maven.compiler.release属性,会退回 source/target=1.5 并被 JDK 17 拒绝。排障见 9.2 节 Q2。
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 编译与运行验证
编译(mvn 读取 JAVA_HOME 使用 JDK 17):
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk
cd /opt/math-demo && mvn compile 2>&1 | tail -6
输出:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 22.618 s
[INFO] Finished at: 2026-10-14T15:28:36Z
[INFO] ------------------------------------------------------------------------
运行。注意必须用 $JAVA_HOME/bin/java 显式调用 JDK 17(PATH 上的 java 是 1.8,运行 major 61 的 class 会报错,排障见 9.1 节 Q1):
M3=/root/.m2/repository/org/apache/commons/commons-math3/3.6.1/commons-math3-3.6.1.jar
$JAVA_HOME/bin/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 的平均),结果正确,说明依赖已正确引入且可运行。
4.6 JDK 8 运行时兼容验证
CentOS 8 生产环境大量存量应用仍跑在 JDK 8 上。commons-math3 3.6.1 本体是 Java 5 字节码(major=49),天然兼容;再把工程代码按 release 8 编译后,交由系统默认 JDK 8 运行时验证完整链路:
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk
cd /opt/math-demo
$JAVA_HOME/bin/javac --release 8 -encoding UTF-8 -cp ~/.m2/repository/org/apache/commons/commons-math3/3.6.1/commons-math3-3.6.1.jar -d classes8 src/main/java/demo/MathDemo.java
javap -v -cp classes8 demo.MathDemo 2>/dev/null | grep major
java -version 2>&1 | head -1
M3=/root/.m2/repository/org/apache/commons/commons-math3/3.6.1/commons-math3-3.6.1.jar
java -Dfile.encoding=UTF-8 -cp classes8:$M3 demo.MathDemo ttest
输出:
major version: 52
openjdk version "1.8.0_312"
== TTest(配对 t 检验 / 同方差 t 检验) ==
pairedT(before, after) = -13.717203674463095
pairedTTest p 值(双侧) = 2.5795569554518058E-6
homoscedasticT(before, after) = -1.596337345388562
homoscedasticTTest p 值(双侧) = 0.13273255836476072
逐项说明:--release 8 产出 major=52(Java 8)字节码;随后直接用 PATH 上的 java(1.8.0_312)运行,配对 t 检验完整执行成功。结论:math3 3.6.1 + JDK 8 运行时完全兼容,存量 JDK 8 应用可直接引入。
五、离线安装方案(B:官方二进制包)
适合内网隔离、无法访问中央仓库的环境。官方 commons-math3-3.6.1-bin.tar.gz 内含主 jar 与 javadoc/sources,且零传递依赖,解压即用,无需补任何第三方 jar。
5.1 方案说明与适用场景
本方案从官方下载目录获取二进制包,做哈希校验后解压,再用 javac/java -cp 直接编译运行验证。全程不依赖 Maven;JDK 用系统自带的 1.8 或 JDK 17 均可(math3 是 major=49 字节码)。
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
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
核对官方 sha256(官方只提供 sha1/sha256/asc,没有 sha512 校验文件):
ls -l commons-math3-3.6.1-bin.tar.gz
cat commons-math3-3.6.1-bin.tar.gz.sha256
sha256sum commons-math3-3.6.1-bin.tar.gz
gzip -t commons-math3-3.6.1-bin.tar.gz && echo "gzip OK"
输出:
-rw-r--r-- 1 root root 18577952 Oct 14 15:53 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 OK
验证点:包大小 18,577,952 字节,本机计算 sha256 与官方 .sha256 文件一致,gzip 完整性通过。直连截断的排障过程见 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 内含 1402 个条目(jar tf commons-math3-3.6.1.jar | wc -l 实测),顶层包为 org/apache/commons/math3/。用 javap 验证字节码版本:
javap -v -cp commons-math3-3.6.1/commons-math3-3.6.1.jar 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 一致——系统自带的 JDK 8 也能直接加载运行。
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
java -Dfile.encoding=UTF-8 -cp check-classes:commons-math3-3.6.1/commons-math3-3.6.1.jar MathCheck
输出:
N=10 mean=7.0 sd=3.39934634239519 p50=7.5
commons-math3 OK
验证点:结果与方案 A 完全一致。本步 javac/java 用的是系统默认 JDK 8(math3 为 major=49 字节码,JDK 8 编译运行均可),说明不依赖 Maven、不依赖 JDK 17、纯 jar 直跑同样可用。
六、方案对比与选择建议
两种方案各有取舍,本节汇总关键差异并给出选型建议。
| 维度 | 方案 A:Maven 依赖 | 方案 B:官方二进制包 |
|---|---|---|
| 是否需联网 | 构建时需访问中央仓库 | 仅下载阶段需联网(可离线分发) |
| 安装方式 | 声明依赖自动下载 | 手动下载 + 校验 + 解压 |
| 依赖完整性 | 自动解析(零传递依赖,只有 math3 一个 jar) | 零传递依赖,主 jar 解压即用 |
| JDK 要求 | 编译需 JDK 17(release 17 示例);仅运行可用 JDK 8 | 编译运行均可用 JDK 8 或 17 |
| 附加产物 | 仅主 jar | 附带 javadoc/sources/tests jar 与 docs 目录 |
| 适用场景 | CI/可联网开发 | 内网隔离、离线运行、JDK 8 存量环境 |
选择建议:可联网的新工程选方案 A(配合 4.2 节 JAVA_HOME 切换);内网隔离或 JDK 8 存量环境选方案 B(一次校验下载后任意分发,JDK 8 即可编译运行)。两方案的 MathCheck 实测输出一致,可放心互换。
七、配置说明
Commons Math 是纯类库,没有任何配置文件。CentOS 8 上运行期需要关注的"配置"集中在 JAVA_HOME 与编码两件事,本节逐项说明实测要点。
JAVA_HOME 持久化:CentOS 8 的 Maven 由 JAVA_HOME 决定所用 JDK,写进 profile 脚本对所有登录会话生效:
echo "export JAVA_HOME=/usr/lib/jvm/java-17-openjdk" > /etc/profile.d/java17.sh
cat /etc/profile.d/java17.sh
. /etc/profile.d/java17.sh
mvn -v | head -3
输出:
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk
Apache Maven 3.5.4 (Red Hat 3.5.4-5)
Maven home: /usr/share/maven
Java version: 17.0.1, vendor: Red Hat, Inc., runtime: /usr/lib/jvm/java-17-openjdk-17.0.1.0.12-2.el8_5.x86_64
java -version 2>&1 | head -1
输出:
openjdk version "1.8.0_312"
逐项解读:/etc/profile.d/java17.sh 让 Maven 在每个新登录会话中都使用 JDK 17;但 PATH 上的 java 命令仍由系统 alternatives 机制指向 1.8——这是 CentOS 8 的正常行为,不是配置失败。需要命令行 java 也指向 17 时,显式调用 $JAVA_HOME/bin/java,或用 dnf install java-17-openjdk-devel 后经 alternatives 调整系统默认(会影响全局,谨慎操作)。
其余配置要点:
- 源码编码:
javac带-encoding UTF-8,Maven 工程设project.build.sourceEncoding=UTF-8(见 4.3 节)。 - 运行时编码:locale 为 POSIX/C 时运行加
-Dfile.encoding=UTF-8,中文输出才不乱码(排障见 9.3 节 Q3)。 - JVM 内存:库本身对内存无特殊要求,本文全部示例均以 JVM 默认参数运行;处理超大样本时按需自行追加
-Xms/-Xmx启动参数。
八、升级、降级与多版本管理
本节说明版本变更的实际操作空间与 math3/math4 共存方法。
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),可在同一 classpath 共存,便于迁移期渐进替换。做法:把 math4 各模块 jar(commons-math4-core/legacy/legacy-core/legacy-exception,4.0-beta1)与 math3 jar 一起放入 -cp,代码里 math3 类正常 import,math4 类写全限定名(如 org.apache.commons.math4.legacy.stat.descriptive.DescriptiveStatistics)。共存验证的完整实测(源码、命令、逐行回显)见第 1 篇《Ubuntu 22.04 安装 Apache Commons Math 指南》8.2 节,两个平台的 JVM 行为一致,可直接照做。
8.3 jar 目录式多版本管理
离线场景可在 /opt/math-jars 下按版本建目录并存多套 jar(如 commons-math3-3.6.1/ 与 commons-math-4.0-beta1/),运行时用 -cp 显式指定所用目录中的 jar,互不干扰。
九、常见问题(FAQ)
Q1:export JAVA_HOME=/usr/lib/jvm/java-17-openjdk 后运行程序报 UnsupportedClassVersionError 怎么办?
完整实测现象(把 release 17 编译的 class 交给 PATH 上的 java 1.8 运行):
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.UnsupportedClassVersionError: MathCheck has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 52.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:473)
at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
(输出节选,堆栈其后还有十余行 at java.lang.ClassLoader.loadClass 等帧,最终 EXIT=1。)
定位:CentOS 8 上 export JAVA_HOME 只影响 mvn 等读取该变量的工具,不影响 PATH 上的 java 命令——java 仍由系统 alternatives 指向 1.8.0_312,而 class 文件版本 61.0(Java 17)无法在只识别 52.0(Java 8)的运行时上加载。解决:显式调用 JDK 17 的 java:
M3=/root/.m2/repository/org/apache/commons/commons-math3/3.6.1/commons-math3-3.6.1.jar
$JAVA_HOME/bin/java -Dfile.encoding=UTF-8 -cp target/classes:$M3 MathCheck
输出:
N=10 mean=7.0 sd=3.39934634239519 p50=7.5
commons-math3 OK
另两条出路:按 4.6 节把工程字节码降到 --release 8 由 JDK 8 直接运行;或按第七章持久化 JAVA_HOME 并显式使用 $JAVA_HOME/bin/java。注意 commons-math3 自身是 major=49 字节码,此坑与库无关,是工程类与运行时版本不匹配所致。
Q2: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.
定位:CentOS 8 的 Maven 3.5.4 同样默认绑定老版 maven-compiler-plugin(3.1),不认识 maven.compiler.release 属性,按 1.5 处理后被 JDK 17 的 javac 拒绝。解决:在 pom 的 <build><plugins> 中显式固定 maven-compiler-plugin 版本为 3.11.0(见 4.3 节 pom 全文)。修复后按 4.5 节实测 BUILD SUCCESS。
Q3:运行时中文输出变成 ??? 怎么办?
系统 locale 为 POSIX/C 时,JVM 默认输出编码是 ASCII,中文字符无法映射。实测对比:不加参数运行时中文变问号,数字结果不受影响。解决:运行时追加 JVM 系统属性 -Dfile.encoding=UTF-8(见 4.5 节运行命令),编译侧 javac 加 -encoding UTF-8、Maven 工程设 project.build.sourceEncoding=UTF-8。4.6 节 JDK 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 通过。教训:任何二进制包必须做哈希校验后再解压。
十、卸载与清理
Commons Math 不做系统级安装,删除 jar、工程与缓存即可完全清理:
rm -rf /opt/math-demo /opt/math-jars
rm -f /etc/profile.d/java17.sh
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 17 与 Maven(JDK 8 是系统默认组件,建议保留):
dnf remove -y java-17-openjdk java-17-openjdk-devel maven
⚠️ 注意:
dnf remove仅移除软件包;本文的示例程序与 jar 均在/opt与~/.m2,按上方命令清理即可,无残留系统服务或开机项。移除 JDK 17 前确认没有其他应用依赖$JAVA_HOME。
十一、参考链接
- 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/