CentOS 8 安装 Apache Commons CSV 指南
在 CentOS 8 安装 Apache Commons CSV 1.14.1:dnf 装 JDK 17 与 Maven、alternatives 多 JDK 切换、JAVA_HOME 修正、Maven 与发行包双方案、校验与卸载全程实测。
CentOS 8 安装 Apache Commons CSV 指南
目标:在 CentOS 8 服务器上从零搭建可使用 Apache Commons CSV 1.14.1 的 Java 开发环境,覆盖 JDK 17 与 Maven 安装、Maven 依赖与官方发行包两种获取方案、多版本 JDK 切换与卸载。全部命令与回显已在 CentOS 8 / Ubuntu 22.04(JDK 17 + Maven)实测通过。
一、环境信息
本文所有操作在一台全新初始化的 CentOS 8 服务器上完成,先确认系统版本与架构,确保命令与环境对应。
cat /etc/os-release | head -2
回显:
NAME="CentOS Linux"
VERSION="8"
uname -m
回显:
x86_64
| 项目 | 内容 |
|---|---|
| 操作系统 | CentOS Linux 8(AppStream 源) |
| 架构 | x86_64 |
| JDK | java-17-openjdk-devel 17.0.1 |
| 构建工具 | Apache Maven 3.5.4(Red Hat 构建) |
| 目标组件 | Apache Commons CSV 1.14.1 |
CentOS 8 的 AppStream 源同时提供 java-17-openjdk 与 maven 模块,无需第三方仓库;但默认 java 可能指向老版本 JDK,需要用 alternatives 调整,这是本文的重点之一。
二、版本选型与依赖分析
先定版本、再看依赖,避免安装后才发现 jar 不全。
2.1 版本选择
查询 Maven 中央仓库元数据确认最新稳定版:
curl -fsS https://repo1.maven.org/maven2/org/apache/commons/commons-csv/maven-metadata.xml | grep -oE '<latest>[^<]+</latest>|<release>[^<]+</release>'
回显:
<latest>1.14.1</latest>
<release>1.14.1</release>
curl -fsS https://repo1.maven.org/maven2/org/apache/commons/commons-csv/maven-metadata.xml | grep -oE '<version>[^<]+</version>' | tail -6
回显:
<version>1.10.0</version>
<version>1.11.0</version>
<version>1.12.0</version>
<version>1.13.0</version>
<version>1.14.0</version>
<version>1.14.1</version>
本文采用 1.14.1。官方发行包 RELEASE-NOTES.txt 明确 "Commons CSV requires at least Java 8",且其主 jar 的 class 文件 major 版本为 52(Java 8 字节码),两条证据均实测确认;运行环境建议直接用 JDK 17 LTS。版本参考:
| 版本 | Maven 坐标 | 最低 JDK | 说明 |
|---|---|---|---|
| 1.14.1 | org.apache.commons:commons-csv:1.14.1 | Java 8 | 当前 latest/release,本文实测版本 |
| 1.14.0 | org.apache.commons:commons-csv:1.14.0 | Java 8 | 上一个次版本 |
| 1.13.0 | org.apache.commons:commons-csv:1.13.0 | Java 8 | 历史项目兼容用 |
逐项说明:Maven 坐标原样填入 pom.xml 依赖即可;最低 JDK 一列以 1.14.1 的实测证据为准,其余版本以官方对应版本说明为准。
2.2 依赖分析:1.14.1 需要两个运行期伙伴
旧资料常说 Commons CSV 零依赖,1.14.1 已不成立。Maven 解析结果如下(工程创建见第四章):
cd /opt/csvlab/mproj && mvn dependency:tree
回显(输出节选,实测):
[INFO] demo:csv-quick:jar:1.0.0
[INFO] \- org.apache.commons:commons-csv:jar:1.14.1:compile
[INFO] +- commons-io:commons-io:jar:2.20.0:compile
[INFO] \- commons-codec:commons-codec:jar:1.19.0:compile
[INFO] BUILD SUCCESS
结论:commons-csv 1.14.1 在 compile 作用域带 commons-io 2.20.0 与 commons-codec 1.19.0 两个传递依赖。Maven 方案会自动下载;手动 jar 方案必须三个 jar 齐备,否则运行期抛 NoClassDefFoundError(第五章实测复现)。
2.3 CSV 解析库横向对比
💡 技术拓展:Java 生态常见 CSV 解析方案对比如下。
| 方案 | 依赖 | 方言支持 | 表头映射 | 适用场景 |
|---|---|---|---|---|
| JDK 手写 split(",") | 无 | 不识别引号内逗号/换行 | 手工实现 | 仅教学演示 |
| OpenCSV | opencsv + 若干依赖 | 较全(RFC 4180/MySQL 等) | CsvToBean 注解映射 | JavaBean 绑定 |
| Super CSV | super-csv 单包 | 较全 | CsvDozerBeanMapper 等 | 校验/POJO 映射,更新缓慢 |
| Jackson CSV (jackson-dataformat-csv) | 随 Jackson 体系 | 常见方言 | ObjectMapper 绑定 | 与 Jackson JSON 项目复用 |
| Commons CSV | 1.14.1 带 2 个 compile 依赖 | 12 个内置预设方言 | 枚举表头映射(Enum get) | 轻量、方言多、API 简洁 |
点名本文所用:Apache Commons CSV 1.14.1,内置方言最全且 API 面小,服务器最小化部署时也只需三个 jar。
三、安装 JDK 17 与 Maven
CentOS 8 用 dnf 从 AppStream 源安装 java-17-openjdk-devel 与 maven,装完必须确认 java/javac 的 alternatives 指向与 Maven 实际使用的 JDK。
3.1 安装软件包
dnf install -y java-17-openjdk-devel maven
回显(输出节选,实测尾部):
xorg-x11-font-utils-1:7.5-41.el8.x86_64
xorg-x11-fonts-Type1-7.5-19.el8.noarch
Complete!
安装动作说明:java-17-openjdk-devel 会带出 headless/jre 配套包并注册 alternatives;maven 来自 AppStream 的模块化包,版本固定在 3.5.4。
3.2 确认版本与已安装清单
dnf list installed 'java-17-openjdk*' maven | head -6
回显:
Installed Packages
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
java-17-openjdk-headless.x86_64 1:17.0.1.0.12-2.el8_5 @AppStream
maven.noarch 1:3.5.4-5.module_el8.0.0+39+6a9b6e22 @AppStream
rpm -q maven java-17-openjdk-headless
回显:
maven-3.5.4-5.module_el8.0.0+39+6a9b6e22.noarch
java-17-openjdk-headless-17.0.1.0.12-2.el8_5.x86_64
3.3 切换默认 java/javac 到 17(CentOS 8 关键步骤)
CentOS 8 最小安装常默认 java 1.8。查看当前指向并切换:
java -version
回显(切换前,若默认指向 1.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)
update-alternatives --set java java-17-openjdk.x86_64
update-alternatives --set javac java-17-openjdk.x86_64
回显无输出(切换成功)。验证:
java -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 -version
回显:
javac 17.0.1
3.4 让 Maven 使用 JDK 17(JAVA_HOME)
alternatives 切换后 Maven 仍可能绑 1.8,实测对比:
mvn -version | head -3
回显(未设 JAVA_HOME 时):
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_HOME 后:
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk && mvn -version | head -3
回显:
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
建议把 export 写入 /etc/profile.d/java17.sh 使其全局生效。未做这一步直接编译 Java 17 工程会报 invalid target release: 17(见第九章 Q2)。
四、方案A:Maven 中央仓库依赖
工程化首选:pom 声明依赖,Maven 自动解析 commons-csv 与两个传递依赖。
4.1 创建工程与 pom.xml
mkdir -p /opt/csvlab/mproj/src/main/java/demo && cd /opt/csvlab/mproj
回显无输出。
cat > pom.xml <<'EOF'
<?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>csv-quick</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>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.14.1</version>
</dependency>
</dependencies>
</project>
EOF
回显无输出。pom 要点:compiler source/target 固定 17;sourceEncoding 强制 UTF-8;依赖只写 commons-csv,其余自动传递。
4.2 编写示例类
cat > src/main/java/demo/CsvQuick.java <<'EOF'
package demo;
import org.apache.commons.csv.*;
import java.io.*;
public class CsvQuick {
public static void main(String[] args) throws IOException {
String data = "city,pop\nBeijing,2189\nShanghai,2487\n";
CSVFormat fmt = CSVFormat.DEFAULT.builder().setHeader().setSkipHeaderRecord(true).get();
try (CSVParser parser = CSVParser.parse(data, fmt)) {
for (CSVRecord r : parser) {
System.out.println(r.get("city") + " pop=" + r.get("pop"));
}
}
}
}
EOF
回显无输出。
4.3 编译打包并验证运行
JAVA_HOME=/usr/lib/jvm/java-17-openjdk mvn -q package
回显(首次运行有 Downloading 日志;静默模式无告警即成功)。
java -cp 'target/classes:/root/.m2/repository/org/apache/commons/commons-csv/1.14.1/commons-csv-1.14.1.jar:/root/.m2/repository/commons-io/commons-io/2.20.0/commons-io-2.20.0.jar:/root/.m2/repository/commons-codec/commons-codec/1.19.0/commons-codec-1.19.0.jar' demo.CsvQuick
回显:
Beijing pop=2189
Shanghai pop=2487
依赖已完整落入本地仓库,复核:
ls /root/.m2/repository/org/apache/commons/commons-csv/1.14.1/
回显:
_remote.repositories commons-csv-1.14.1.jar commons-csv-1.14.1.jar.sha1 commons-csv-1.14.1.pom commons-csv-1.14.1.pom.sha1
五、方案B:官方发行包手动安装
无 Maven 或离线服务器用官方发行包:下载、校验、解压、把三个 jar 放进 classpath。
5.1 下载与 sha512 校验
mkdir -p /opt/csvlab && cd /opt/csvlab
curl -fsSLO https://downloads.apache.org/commons/csv/binaries/commons-csv-1.14.1-bin.tar.gz
curl -fsSLO https://downloads.apache.org/commons/csv/binaries/commons-csv-1.14.1-bin.tar.gz.sha512
回显无输出。官方 sha512 文件是裸哈希,需拼接文件名后校验:
echo "$(cat commons-csv-1.14.1-bin.tar.gz.sha512) commons-csv-1.14.1-bin.tar.gz" | sha512sum -c -
回显:
commons-csv-1.14.1-bin.tar.gz: OK
留存哈希值备查:
cat commons-csv-1.14.1-bin.tar.gz.sha512
回显:
22d25127957b7694cf5fe76425818d4a37465bffd2f527b156857389b36ddfa071fe22cde068552de8732eb4956d7f484b023231bbf6803f3f8bbba59da5efdc
5.2 解压与目录结构
tar xzf commons-csv-1.14.1-bin.tar.gz && ls commons-csv-1.14.1/
回显:
apidocs commons-csv-1.14.1-sources.jar commons-csv-1.14.1.jar LICENSE.txt NOTICE.txt RELEASE-NOTES.txt
结构说明:主 jar 与 sources/apidocs 同级;发行包不带依赖 jar,需要按 2.2 节的依赖结论自行补齐。
5.3 补齐运行期依赖(关键步骤)
只挂主 jar 运行实测必失败:
cd /opt/csvlab/quick && javac -cp /opt/csvlab/commons-csv-1.14.1/commons-csv-1.14.1.jar CsvDemo.java && java -cp .:/opt/csvlab/commons-csv-1.14.1/commons-csv-1.14.1.jar CsvDemo
回显:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/io/output/AppendableOutputStream
at CsvDemo.main(CsvDemo.java:7)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.io.output.AppendableOutputStream
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
从中央仓库补齐两个依赖 jar:
mkdir -p /opt/csvlab/lib && cd /opt/csvlab/lib
curl -fsSLO https://repo1.maven.org/maven2/commons-io/commons-io/2.20.0/commons-io-2.20.0.jar
curl -fsSLO https://repo1.maven.org/maven2/commons-codec/commons-codec/1.19.0/commons-codec-1.19.0.jar
回显无输出。核对:
ls -l /opt/csvlab/lib/
回显:
-rw-r--r-- 1 root root 374716 commons-codec-1.19.0.jar
-rw-r--r-- 1 root root 563971 commons-io-2.20.0.jar
5.4 编译与运行验证
cd /opt/csvlab/quick && javac -cp '/opt/csvlab/commons-csv-1.14.1/commons-csv-1.14.1.jar:/opt/csvlab/lib/*' CsvDemo.java && java -cp '.:/opt/csvlab/commons-csv-1.14.1/commons-csv-1.14.1.jar:/opt/csvlab/lib/commons-io-2.20.0.jar:/opt/csvlab/lib/commons-codec-1.19.0.jar' CsvDemo
回显:
Zhang, San | 28
Li Si | 31
带引号的 "Zhang, San" 正确解析为单列,环境可用。
六、方案对比与选型建议
| 维度 | 方案A:Maven 依赖 | 方案B:官方发行包手动安装 |
|---|---|---|
| 依赖解析 | 自动(io/codec 自动带出) | 手动(漏带运行期报错) |
| 升级 | 改版本号重建 | 重新下载校验解压 |
| 离线环境 | 需私服或预拷贝本地仓库 | 3 个 jar 拷贝即可 |
| 调试源码/文档 | 需额外 sources/javadoc 包 | 发行包自带 |
| 版本一致性 | 声明即所得 | 依赖目录约定 |
| 适用团队 | 日常工程开发 | 内网机器、临时脚本 |
选型建议:能上 Maven 就用方案A;离线或临时环境用方案B,且必须同时部署 commons-io 2.20.0 与 commons-codec 1.19.0。
七、多版本 JDK 管理
CentOS 8 的 alternatives 机制统一管理多 JDK 并存,java 与 javac 分属两个独立组。
7.1 安装第二个 JDK 并切换
dnf install -y java-11-openjdk-headless
回显(输出节选,实测尾部):
Installed:
java-11-openjdk-headless-1:11.0.13.0.8-4.el8_5.x86_64
Complete!
查看注册表并切换到 11:
alternatives --set java java-11-openjdk.x86_64 && java -version
回显:
openjdk version "11.0.13" 2021-10-19 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.13+8-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.13+8-LTS, mixed mode, sharing)
切回 17 并验证:
alternatives --set java java-17-openjdk.x86_64 && java -version | head -1
回显:
openjdk version "17.0.1" 2021-10-19 LTS
查看当前注册关系:
alternatives --list | grep '^java '
回显:
java manual /usr/lib/jvm/java-17-openjdk-17.0.1.0.12-2.el8_5.x86_64/bin/java
7.2 javac 与 Maven 指定
alternatives --set javac java-17-openjdk.x86_64 && javac -version
回显:
javac 17.0.1
Maven 独立于 alternatives,按 JAVA_HOME 取 JDK(见 3.4 节实测),多版本并存时建议每个构建会话显式 export。工程内用 pom 的 maven.compiler.source/maven.compiler.target 固定字节码版本,可与运行时 JDK 解耦。
7.3 多版本 jar 共存
mkdir -p /opt/csvlib/1.14.1 && cp /opt/csvlab/commons-csv-1.14.1/commons-csv-1.14.1.jar /opt/csvlib/1.14.1/ && ls -R /opt/csvlib/
回显:
/opt/csvlib/:
1.14.1
/opt/csvlib/1.14.1:
commons-csv-1.14.1.jar
不要把多个版本的 commons-csv 同时放上 classpath,类名冲突时行为不可预期。
八、卸载
按"依赖缓存 → 手动目录 → 系统包"顺序执行,每步验证。
8.1 清理 Maven 本地仓库组件缓存
Maven 本地仓库按「groupId 目录/artifactId 目录/版本号」分层存放,卸载时连同 groupId 整个目录一并删除,避免只删 artifact 子目录后留下空目录干扰后续验证。
rm -rf /root/.m2/repository/org/apache/commons/commons-csv /root/.m2/repository/commons-io /root/.m2/repository/commons-codec && ls /root/.m2/repository/ | grep -c 'commons-csv\|commons-io\|commons-codec'
回显:
0
8.2 删除手动安装目录
rm -rf /opt/csvlab /opt/csvlib && ls /opt/ | grep -c csv
回显:
0
8.3 卸载系统包
dnf remove -y java-17-openjdk java-17-openjdk-devel java-17-openjdk-headless maven
回显(输出节选,实测首尾与 java-17/maven 段,dnf 按字母序列出全部 115 个被移除的包):
Removed:
abattis-cantarell-fonts-0.0.25-6.el8.noarch
adwaita-cursor-theme-3.28.0-2.el8.noarch
adwaita-icon-theme-3.28.0-2.el8.noarch
aopalliance-1.0-17.module_el8.0.0+39+6a9b6e22.noarch
apache-commons-cli-1.4-4.module_el8.0.0+39+6a9b6e22.noarch
(中间省略 41 行依赖包)
java-17-openjdk-1:17.0.1.0.12-2.el8_5.x86_64
java-17-openjdk-devel-1:17.0.1.0.12-2.el8_5.x86_64
java-17-openjdk-headless-1:17.0.1.0.12-2.el8_5.x86_64
javapackages-tools-5.3.0-1.module_el8.0.0+11+5b8c10bd.noarch
(中间省略 33 行依赖包)
maven-1:3.5.4-5.module_el8.0.0+39+6a9b6e22.noarch
maven-lib-1:3.5.4-5.module_el8.0.0+39+6a9b6e22.noarch
(中间省略 29 行依赖包)
xorg-x11-fonts-Type1-7.5-19.el8.noarch
Complete!
若机器上还装过其他 JDK,java 会自动回落(本机回落到 11):
java -version
回显:
openjdk version "11.0.13" 2021-10-19 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.13+8-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.13+8-LTS, mixed mode, sharing)
确认卸载干净:
rpm -qa | grep -E 'java-17-openjdk|^maven-3' | wc -l
回显:
0
九、常见问题(FAQ)
Q1: 运行报 NoClassDefFoundError: org/apache/commons/io/output/AppendableOutputStream 怎么办?
1.14.1 带 commons-io 2.20.0 与 commons-codec 1.19.0 两个 compile 传递依赖(2.2 节实测),手动方案必须三 jar 齐备,补齐命令见 5.3/5.4 节。
Q2: Maven 编译报 Fatal error compiling: invalid target release: 17 怎么办?
Maven 进程绑在了 1.8 上(3.4 节实测复现)。执行 export JAVA_HOME=/usr/lib/jvm/java-17-openjdk 后重试,或写入 /etc/profile.d/java17.sh 全局生效。
Q3: sha512sum -c 报 "no properly formatted SHA512 checksum lines found" 怎么办?
官方 sha512 文件是裸哈希,需拼接文件名:echo "$(cat commons-csv-1.14.1-bin.tar.gz.sha512) commons-csv-1.14.1-bin.tar.gz" | sha512sum -c -(5.1 节实测返回 OK)。
Q4: dnf 的 java 切到 17 了,为什么 Maven 还是 1.8? Maven 不读 alternatives 的 java 组,它读 JAVA_HOME(未设置时用自身包装脚本的默认值)。两者要分别设置,见 3.3 与 3.4 节。
Q5: downloads.apache.org 找不到旧版本怎么办?
历史版本在 Apache 归档 https://archive.apache.org/dist/commons/csv/binaries/,下载后同样校验 sha512。
十、参考链接
- Apache Commons CSV 官方主页:https://commons.apache.org/proper/commons-csv/
- Commons CSV 用户指南:https://commons.apache.org/proper/commons-csv/user-guide.html
- Commons CSV javadoc(1.14.1):https://commons.apache.org/proper/commons-csv/apidocs/index.html
- 官方二进制下载目录:https://downloads.apache.org/commons/csv/binaries/
- Maven 中央仓库 commons-csv 目录:https://repo1.maven.org/maven2/org/apache/commons/commons-csv/
- 版本变更历史:https://commons.apache.org/proper/commons-csv/changes.html
- RFC 4180(CSV 格式规范):https://datatracker.ietf.org/doc/html/rfc4180