CentOS 8 安装 Apache Commons Numbers 指南
在 CentOS 8 上切换 vault 归档源并安装 JDK 17 与 Maven,以 Maven BOM 或官方 bin 包两种方式接入 Apache Commons Numbers 1.3 多模块数学库并完成最小验证工程实测。
CentOS 8 安装 Apache Commons Numbers 指南
目标:在 CentOS 8 服务器上完成 Apache Commons Numbers 1.3 的依赖安装与最小可运行验证,重点处理 CentOS 8 EOL 后软件源失效问题,覆盖 Maven 在线集成与官方 bin 包离线直跑两条路线,全部命令已在 CentOS 8 实测通过。
一、环境信息
- 操作系统:CentOS Linux release 8.4.2105(x86_64)
- 架构:x86_64
- JDK:OpenJDK 17.0.1(dnf 包
java-17-openjdk-devel-1:17.0.1.0.12-2.el8_5) - 构建工具:Apache Maven 3.5.4(dnf 包
maven-3.5.4-5.module_el8.0.0) - 软件源:CentOS 8 已 EOL,mirrorlist 已失效,实测切换到
mirrors.aliyun.com/centos-vault/8.5.2111归档源 - 组件版本:Apache Commons Numbers 1.3(要求 Java 8 及以上,字节码版本 52,2026 年 4 月发布)
- Maven 坐标:
org.apache.commons:commons-numbers-bom:1.3(BOM),按需引用commons-numbers-core、commons-numbers-fraction、commons-numbers-angle等 11 个运行时模块 - 工作目录:
/root/commons-numbers-demo
二、前置条件
- 具备 root 权限的 CentOS 8 服务器一台;
- 服务器可访问公网(归档软件源与 Maven 中央仓库 repo1.maven.org),离线环境请直接采用方案 B;
- 磁盘剩余空间不低于 3 GB(java-17-openjdk-devel 连同依赖约占 500 MB);
- 明确接受 CentOS 8 已于 2021 年 12 月 31 日停止维护这一事实:本指南安装的系统包停留在 EOL 前的最后版本(JDK 17.0.1、Maven 3.5.4),生产环境建议规划迁移到仍在维护的 RHEL 8/9、Rocky Linux 8/9 或 AlmaLinux。
三、版本选型说明
Apache Commons Numbers 是 Apache 官方的轻量级数值计算库,由多个功能独立的模块组成。官方下载目录的当前版本列表如下(实测输出):
$ curl -s https://downloads.apache.org/commons/numbers/
1.0/ 1.1/ 1.2/ 1.3/
1.3 为 1.x 稳定系列的最新版本,本指南全部实验基于 1.3。
Numbers 1.3 的运行时模块共 11 个(另有 commons-numbers-bom 依赖清单与 commons-numbers-examples 示例包,不属于运行时依赖),逐一列明如下:
| 模块 artifactId | 核心类 | 职责 |
|---|---|---|
| commons-numbers-core | Precision、ArithmeticUtils、Sum、DD | 浮点比较、整数运算与溢出、扩展精度求和 |
| commons-numbers-angle | Angle、Reduce、CosAngle | 角度、弧度、圈数三种单位与归一化、夹角余弦 |
| commons-numbers-arrays | Selection、SortInPlace、MultidimensionalCounter | 顺序统计量、同步排序、多维计数器 |
| commons-numbers-combinatorics | Factorial、BinomialCoefficient、Stirling、Combinations | 阶乘、二项式系数、斯特林数、组合枚举 |
| commons-numbers-complex | Complex | 复数运算 |
| commons-numbers-field | FP64、FP64Field、FractionField | 可插拔域代数抽象 |
| commons-numbers-fraction | Fraction、BigFraction、ContinuedFraction | 分数与连分数 |
| commons-numbers-gamma | Gamma、LogGamma、Digamma、Erf、Beta | 伽马函数族与误差函数 |
| commons-numbers-primes | Primes | 素数判定、生成、因子分解 |
| commons-numbers-quaternion | Quaternion、Slerp | 四元数与球面线性插值 |
| commons-numbers-rootfinder | BrentSolver | Brent 法求根 |
💡 技术拓展:模块选型建议——Numbers 采用按模块拆分发布的设计,下游按需引入即可,不必全量引入。常见组合:只需浮点比较与整数运算选
commons-numbers-core(零依赖);涉及分数精确计算补commons-numbers-fraction(会传递依赖 core);需要特殊函数(伽马、误差函数)补commons-numbers-gamma;复数、四元数分别对应complex、quaternion。本文验证工程选用 core、fraction、angle 三个模块,覆盖数论、分数、角度三类典型能力。
四、安装方案 A:Maven 依赖(推荐)
4.1 方案说明
Maven 方案通过 commons-numbers-bom 统一管理 11 个模块的版本号,工程里只写 groupId 与 artifactId,升级版本只改一处。CentOS 8 场景下该方案包含三个步骤:修复 EOL 软件源、安装 JDK 与 Maven、验证构建。
4.2 安装 JDK 17 与 Maven
直接安装会遇到 EOL 源失效(实测复现):
dnf install -y java-17-openjdk-devel maven
实测回显(输出节选):
CentOS Linux 8 - AppStream 34 B/s | 38 B 00:01
Errors during downloading metadata for repository 'appstream':
- Curl error (6) for 'http://mirrorlist.centos.org/?release=8&arch=x86_64&repo=AppStream&infra=$infra': Could not resolve host: mirrorlist.centos.org
Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: Curl error (6) - Couldn't resolve host
原因:CentOS 8 EOL 后 mirrorlist.centos.org 已下线,必须改用归档源。官方归档为 vault.centos.org,国内访问推荐阿里云镜像 mirrors.aliyun.com/centos-vault/8.5.2111。执行切换:
sed -i -e 's|mirrorlist=|#mirrorlist=|g' -e 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-Linux-*.repo
由于本机到 vault.centos.org(CloudFront 海外节点)的连通性不稳定,实测进一步把 baseurl 指向阿里云归档镜像(以可跑通为准):
sed -i 's|baseurl=http://vault.centos.org/$contentdir/$releasever|baseurl=http://mirrors.aliyun.com/centos-vault/8.5.2111|g' /etc/yum.repos.d/CentOS-Linux-*.repo
grep '^baseurl' /etc/yum.repos.d/CentOS-Linux-AppStream.repo /etc/yum.repos.d/CentOS-Linux-BaseOS.repo
dnf clean all
dnf makecache
实测回显:
/etc/yum.repos.d/CentOS-Linux-AppStream.repo:baseurl=http://mirrors.aliyun.com/centos-vault/8.5.2111/AppStream/x86_64/os/
/etc/yum.repos.d/CentOS-Linux-BaseOS.repo:baseurl=http://mirrors.aliyun.com/centos-vault/8.5.2111/BaseOS/x86_64/os/
CentOS Linux 8 - AppStream 1.4 MB/s | 9.4 MB 00:06
CentOS Linux 8 - BaseOS 2.0 MB/s | 11 MB 00:05
Metadata cache created.
💡 技术拓展:CentOS 8 EOL 后的软件源选型对比——方式一是官方归档 vault.centos.org(地址稳定但海外带宽一般,部分地区可能被限流);方式二是国内公共镜像的 centos-vault 目录(如 mirrors.aliyun.com、mirrors.tuna.tsinghua.edu.cn,速度快且同步及时);方式三是迁移到 Rocky/AlmaLinux 的 8.x 源(rpm 兼容,但需改仓库指向)。本文采用方式二完成实测,方式一作为官方路径保留在 sed 命令中。
重新执行安装:
dnf install -y java-17-openjdk-devel maven
输出节选(实测首尾,共 143 个包):
Installing:
java-17-openjdk-devel x86_64 1:17.0.1.0.12-2.el8_5 appstream 5.1 M
maven x86_64 1:3.5.4-5.module_el8.0.0+39+6a9b6 appstream 27 k
Installing weak dependencies:
java-1.8.0-openjdk x86_64 1:1.8.0.312.b07-2.el8_5 appstream 341 k
Running scriptlet: java-1.8.0-openjdk-headless-1:1.8.0.312.b07-2.el8_5. 1/1
Installing : java-1.8.0-openjdk-headless-1:1.8.0.312.b07-2.el 53/143
Verifying : java-17-openjdk-headless-1:17.0.1.0.12-2.el8_5. 143/143
Complete!
4.3 把默认 JDK 切换到 17
CentOS 8 安装 java-17 时会作为弱依赖带出 java-1.8.0,并把系统默认 java 指向 8(实测复现):
java -version
实测回显:
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)
用 alternatives 把 java 与 javac 都切到 17,并设置 JAVA_HOME:
alternatives --set java java-17-openjdk.x86_64
alternatives --set javac java-17-openjdk.x86_64
echo 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk' | tee /etc/profile.d/java17.sh
source /etc/profile.d/java17.sh
java -version
javac -version
实测回显:
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)
javac 17.0.1
验证 Maven 运行环境(Maven 自身仍跑在系统默认 JVM 上):
mvn -version
实测回显:
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
验证结果:JDK 17.0.1 与 Maven 3.5.4 就绪,Maven 已运行在 JDK 17 上。若 mvn -version 仍显示 1.8.0_312,重新登录或先执行 source /etc/profile.d/java17.sh。
4.4 创建工程并引入依赖
mkdir -p /root/commons-numbers-demo/src/main/java
vi /root/commons-numbers-demo/pom.xml
pom.xml 完整内容(BOM 管 11 个模块版本,本工程先引 core、fraction、angle 三个模块):
<?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.numbers</groupId>
<artifactId>commons-numbers-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>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-numbers-bom</artifactId>
<version>1.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-numbers-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-numbers-fraction</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-numbers-angle</artifactId>
</dependency>
</dependencies>
<build>
<finalName>commons-numbers-demo</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>Demo</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
💡 技术拓展:依赖版本管理方式对比——方式一是如上使用
commons-numbers-bom的importscope,11 个模块版本统一由 BOM 锁定;方式二是每个依赖单独写<version>1.3</version>。前者多模块协同升级只需改一行,后者灵活但易出现模块间版本漂移。Numbers 1.3 起 11 个模块同版本发布,推荐方式一。本文采用方式一。
4.5 编写最小验证代码
vi /root/commons-numbers-demo/src/main/java/Demo.java
Demo.java 完整内容:
import org.apache.commons.numbers.angle.Angle;
import org.apache.commons.numbers.core.ArithmeticUtils;
import org.apache.commons.numbers.fraction.Fraction;
public class Demo {
public static void main(String[] args) {
System.out.println("---- core: ArithmeticUtils ----");
System.out.println("gcd(48, 18) = " + ArithmeticUtils.gcd(48, 18));
System.out.println("pow(2, 10) = " + ArithmeticUtils.pow(2, 10));
System.out.println("---- fraction: Fraction ----");
System.out.println("Fraction.of(1, 3).add(Fraction.of(1, 6)) = "
+ Fraction.of(1, 3).add(Fraction.of(1, 6)));
System.out.println("Fraction.of(2, 4)(构造即约分) = " + Fraction.of(2, 4));
System.out.println("---- angle: Angle ----");
System.out.println("Angle.Deg.of(90).toRad().getAsDouble() = "
+ Angle.Deg.of(90).toRad().getAsDouble());
System.out.println("commons-numbers 1.3 OK");
}
}
4.6 编译打包与运行
cd /root/commons-numbers-demo
mvn -q -B package
mvn -q -B package 在成功时无任何输出,退出码为 0(实测 BUILD_EXIT=0)。查看产物并运行:
ls -l target/commons-numbers-demo.jar
java -Dfile.encoding=UTF-8 -Dstdout.encoding=UTF-8 -jar target/commons-numbers-demo.jar
实测回显:
-rw-r--r-- 1 root root 70383 Oct 15 01:09 target/commons-numbers-demo.jar
---- core: ArithmeticUtils ----
gcd(48, 18) = 6
pow(2, 10) = 1024
---- fraction: Fraction ----
Fraction.of(1, 3).add(Fraction.of(1, 6)) = 1 / 2
Fraction.of(2, 4)(构造即约分) = 1 / 2
---- angle: Angle ----
Angle.Deg.of(90).toRad().getAsDouble() = 1.5707963267948966
commons-numbers 1.3 OK
验证结果:shade 插件把 core、fraction、angle 三个模块的类合并进了 70 KB 的 fat jar,gcd、分数加法约分、度转弧度结果全部正确,方案 A 验证通过。
五、安装方案 B:官方 bin 包 + jar 直跑
5.1 方案说明
官方 bin 包把 11 个模块的 jar 打在一个 tarball 里,解压后直接以 classpath 方式运行,全程不需要 Maven,也不依赖任何软件源,适合离线服务器与排障环境。
5.2 下载与完整性校验
cd /opt
curl -O https://downloads.apache.org/commons/numbers/binaries/commons-numbers-1.3-bin.tar.gz
curl -O https://downloads.apache.org/commons/numbers/binaries/commons-numbers-1.3-bin.tar.gz.sha512
cat commons-numbers-1.3-bin.tar.gz.sha512
sha512sum commons-numbers-1.3-bin.tar.gz
实测回显(首行为官方校验文件内容,第二行为本地计算结果,两者一致):
94ab95fce6c7729d07a58c02c3cca384fd74a2d8bb9cdad7c8943c673f2afefc92a67abfbce81437e17428f04863f9b0b32d46f9987346ac3e71ab3116927306 commons-numbers-1.3-bin.tar.gz
94ab95fce6c7729d07a58c02c3cca384fd74a2d8bb9cdad7c8943c673f2afefc92a67abfbce81437e17428f04863f9b0b32d46f9987346ac3e71ab3116927306 commons-numbers-1.3-bin.tar.gz
验证结果:SHA-512 校验一致,包完整。
5.3 解压并查看模块清单
tar xzf commons-numbers-1.3-bin.tar.gz
ls commons-numbers-1.3/
实测回显:
DEPENDENCIES LICENSE.txt NOTICE.txt RELEASE-NOTES.txt
commons-numbers-angle-1.3.jar commons-numbers-gamma-1.3.jar
commons-numbers-arrays-1.3.jar commons-numbers-primes-1.3.jar
commons-numbers-combinatorics-1.3.jar commons-numbers-quaternion-1.3.jar
commons-numbers-complex-1.3.jar commons-numbers-rootfinder-1.3.jar
commons-numbers-core-1.3.jar
commons-numbers-field-1.3.jar
commons-numbers-fraction-1.3.jar
11 个 jar 与第三章模块清单一一对应。
5.4 javac 编译与 java 直跑
将方案 A 的 Demo.java 复制到 /opt/jar-run,不经过 Maven 直接编译运行:
mkdir -p /opt/jar-run/out
cd /opt/jar-run
cp /opt/commons-numbers-1.3/commons-numbers-core-1.3.jar .
cp /opt/commons-numbers-1.3/commons-numbers-fraction-1.3.jar .
cp /opt/commons-numbers-1.3/commons-numbers-angle-1.3.jar .
cp /root/commons-numbers-demo/src/main/java/Demo.java .
javac -encoding UTF-8 -cp 'commons-numbers-core-1.3.jar:commons-numbers-fraction-1.3.jar:commons-numbers-angle-1.3.jar' -d out Demo.java
java -Dfile.encoding=UTF-8 -Dstdout.encoding=UTF-8 -cp 'out:commons-numbers-core-1.3.jar:commons-numbers-fraction-1.3.jar:commons-numbers-angle-1.3.jar' Demo
实测回显:
---- core: ArithmeticUtils ----
gcd(48, 18) = 6
pow(2, 10) = 1024
---- fraction: Fraction ----
Fraction.of(1, 3).add(Fraction.of(1, 6)) = 1 / 2
Fraction.of(2, 4)(构造即约分) = 1 / 2
---- angle: Angle ----
Angle.Deg.of(90).toRad().getAsDouble() = 1.5707963267948966
commons-numbers 1.3 OK
验证结果:与方案 A 输出完全一致,方案 B 验证通过。若只想跑完整模块,classpath 可直接用通配写法 java -cp '/opt/commons-numbers-1.3/*' 主类名。
六、方案对比与选择建议
| 维度 | 方案 A:Maven 依赖 | 方案 B:bin 包 jar 直跑 |
|---|---|---|
| 网络要求 | 需访问 Maven 中央仓库与归档源 | 仅下载一次 tarball,之后完全离线 |
| 版本管理 | BOM 统一管理,升级改一行 | 手动替换 jar,需自己保证模块同版本 |
| EOL 影响 | 需先修复 /etc/yum.repos.d 才能装 JDK 与 Maven | 无影响(已有 JDK 即可) |
| 适合场景 | 常规研发、持续集成 | 离线内网、临时排障、脚本类小工具 |
选择建议:能修复软件源的生产研发环境一律走方案 A;源修复成本高或机器完全离线时用方案 B。
七、配置说明
- alternatives 多版本切换:CentOS 8 的 java 与 javac 各有一套 alternatives 链接,切换用
alternatives --set java java-17-openjdk.x86_64与alternatives --set javac java-17-openjdk.x86_64;可用alternatives --display java查看当前指向。 - JAVA_HOME:推荐写入
/etc/profile.d/java17.sh(内容export JAVA_HOME=/usr/lib/jvm/java-17-openjdk),登录 shell 自动加载;Maven 3.5.4 的运行 JVM 取自系统默认 java 链接,切换后无需再为 Maven 单独配置。 - 编码:CentOS 8 默认 locale 常为 POSIX,运行涉及中文输出的程序统一加
-Dfile.encoding=UTF-8 -Dstdout.encoding=UTF-8;长期方案是dnf install glibc-langpack-zh并把LANG设为C.UTF-8或zh_CN.UTF-8。 - Maven 私服:企业内网可将
commons-numbers-bom与各模块 jar 经mvn deploy发布到内部仓库(如 Nexus、Artifactory),工程内通过<repositories>指向私服即可,坐标不变。 - 模块裁剪:pom 中只保留实际用到的模块。11 个模块互不强依赖,仅 fraction、angle、complex、quaternion 等少数模块传递依赖 core,按需引入不会拉入多余 jar。
八、常见问题(FAQ)
Q1:dnf 报 Failed to download metadata for repo 怎么办?
A:CentOS 8 EOL 的必现问题,按 4.2 节把 mirrorlist 注释掉并把 baseurl 指向 vault 或国内 centos-vault 归档镜像后执行 dnf clean all && dnf makecache。
Q2:为什么装完 java-17 后 java -version 还是 1.8.0_312?
A:java-17-openjdk 的弱依赖会带出 java-1.8.0-openjdk,且 alternatives 自动模式可能选中 8。按 4.3 节显式执行 alternatives --set java java-17-openjdk.x86_64 与 alternatives --set javac java-17-openjdk.x86_64。
Q3:mvn -version 显示的 Java version 与 javac -version 不一致有影响吗?
A:Maven 进程本身跑在 mvn -version 显示的那个 JVM 上,而项目编译用的是 maven-compiler-plugin 调起的 javac。两者不一致不会导致编译版本错误(release/source/target 由 pom 决定),但建议统一到 17 以避免插件兼容性问题。
Q4:dependency:tree 等插件下载时偶发 SSLException 或连接重置? A:老版本 Maven 访问海外中央仓库时偶发 TLS 握手中断,重试一次通常即可;稳定方案是在 settings.xml 中配置国内镜像(如阿里云 Maven 镜像)。
Q5:Fraction 的异常类为什么 catch 不到?
A:org.apache.commons.numbers.fraction.FractionException 是包级私有类,包外只能捕获其公共父类。实测 Fraction.of(1, 0) 抛出 FractionException: Denominator must be different from 0,业务代码用 catch (RuntimeException e) 接住即可。
Q6:Numbers 和 commons-math3 什么关系?
A:Numbers 是 math3 中数值基础部分的现代化拆分重写,API 风格改为不可变对象与静态工厂(如 Fraction.of(1, 3) 而非 new Fraction(1, 3)),模块更细、体积更小。新项目建议直接用 Numbers,math3 停留在 3.6.1 且不再演进。
九、卸载与清理
rm -rf /root/commons-numbers-demo
rm -rf /opt/jar-run
rm -rf /opt/commons-numbers-1.3 /opt/commons-numbers-1.3-bin.tar.gz /opt/commons-numbers-1.3-bin.tar.gz.sha512
rm -rf /root/.m2/repository/org/apache/commons/commons-numbers-*
rm -f /etc/profile.d/java17.sh
dnf remove -y maven java-17-openjdk-devel java-17-openjdk
输出节选(实测):
Dependencies resolved.
Removing:
java-17-openjdk x86_64 1:17.0.1.0.12-2.el8_5 @appstream
java-17-openjdk-devel x86_64 1:17.0.1.0.12-2.el8_5 @appstream
maven noarch 3.5.4-5.module_el8.0.0+39+6a9b6 @appstream
Complete!
要点提示:dnf remove 只移除指定包;java-1.8.0-openjdk 作为弱依赖装上的包如不再需要可另行 dnf remove java-1.8.0-openjdk。卸载后记得用 alternatives --display java 确认剩余 JDK 的指向。
十、参考链接
- Apache Commons Numbers 官方主页:https://commons.apache.org/proper/commons-numbers/
- 官方下载目录:https://downloads.apache.org/commons/numbers/
- Maven 中央仓库 BOM:https://repo1.maven.org/maven2/org/apache/commons/commons-numbers-bom/
- 用户指南(javadoc 入口):https://commons.apache.org/proper/commons-numbers/javadocs/api-release/index.html
- 发行说明(1.3):https://commons.apache.org/proper/commons-numbers/changes-report.html
- CentOS EOL 官方归档:https://vault.centos.org/
- 阿里云 CentOS 归档镜像:https://mirrors.aliyun.com/centos-vault/