CentOS 8 安装 Apache Commons Numbers 指南

在 CentOS 8 上切换 vault 归档源并安装 JDK 17 与 Maven,以 Maven BOM 或官方 bin 包两种方式接入 Apache Commons Numbers 1.3 多模块数学库并完成最小验证工程实测。

Apache Commons NumbersApache Commons Numbers2026/10/15

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

二、前置条件

  1. 具备 root 权限的 CentOS 8 服务器一台;
  2. 服务器可访问公网(归档软件源与 Maven 中央仓库 repo1.maven.org),离线环境请直接采用方案 B;
  3. 磁盘剩余空间不低于 3 GB(java-17-openjdk-devel 连同依赖约占 500 MB);
  4. 明确接受 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-corePrecision、ArithmeticUtils、Sum、DD浮点比较、整数运算与溢出、扩展精度求和
commons-numbers-angleAngle、Reduce、CosAngle角度、弧度、圈数三种单位与归一化、夹角余弦
commons-numbers-arraysSelection、SortInPlace、MultidimensionalCounter顺序统计量、同步排序、多维计数器
commons-numbers-combinatoricsFactorial、BinomialCoefficient、Stirling、Combinations阶乘、二项式系数、斯特林数、组合枚举
commons-numbers-complexComplex复数运算
commons-numbers-fieldFP64、FP64Field、FractionField可插拔域代数抽象
commons-numbers-fractionFraction、BigFraction、ContinuedFraction分数与连分数
commons-numbers-gammaGamma、LogGamma、Digamma、Erf、Beta伽马函数族与误差函数
commons-numbers-primesPrimes素数判定、生成、因子分解
commons-numbers-quaternionQuaternion、Slerp四元数与球面线性插值
commons-numbers-rootfinderBrentSolverBrent 法求根

💡 技术拓展:模块选型建议——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 的 import scope,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。

七、配置说明

  1. 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 查看当前指向。
  2. JAVA_HOME:推荐写入 /etc/profile.d/java17.sh(内容 export JAVA_HOME=/usr/lib/jvm/java-17-openjdk),登录 shell 自动加载;Maven 3.5.4 的运行 JVM 取自系统默认 java 链接,切换后无需再为 Maven 单独配置。
  3. 编码: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。
  4. Maven 私服:企业内网可将 commons-numbers-bom 与各模块 jar 经 mvn deploy 发布到内部仓库(如 Nexus、Artifactory),工程内通过 <repositories> 指向私服即可,坐标不变。
  5. 模块裁剪: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 的指向。

十、参考链接