Ubuntu 22.04 安装 Apache Commons Logging 指南
在 Ubuntu 22.04 上从零引入 Apache Commons Logging 1.4.0,覆盖 Maven 坐标陷阱、Maven 依赖与官方二进制包两套安装方案、JUL 基础配置与升级降级管理,附真实回显与 UnsupportedClassVersionError 排障。
Ubuntu 22.04 安装 Apache Commons Logging 指南
目标:在 Ubuntu 22.04 上从零搭好 Apache Commons Logging 1.4.0(Jakarta Commons Logging,下文简称 JCL)的使用环境,完成版本选型(含 Maven 坐标陷阱)、Maven 在线依赖与官方二进制包离线安装两套方案、基于 JUL 的基础日志配置与升级/降级/多版本管理,并跑通真实日志输出验证。以下全部命令与回显均已在 Ubuntu 22.04(x86_64)实测通过。
一、环境信息
本节先固定本次实测所用软硬件基线,便于读者逐项对照复现。
- 操作系统:Ubuntu 22.04(x86_64,22.04.5 LTS)
- JDK:OpenJDK 17.0.20.1(
java -version实测) - 构建工具:Apache Maven 3.6.3(系统包仓库默认版本)
- 下载工具:curl 7.81.0
- 目标库:Apache Commons Logging 1.4.0(Maven 坐标
commons-logging:commons-logging:1.4.0,2026-06-17 发布) - 传递依赖:无(零传递依赖,实测依赖树确认)
- 依赖来源:
https://downloads.apache.org/commons/logging/binaries/、https://repo1.maven.org/maven2/(网络直连可达) - Maven 示例工程目录:
/opt/logging-demo - 官方二进制包工作目录:
/opt/logging-jars
先确认 JDK 与 Maven 的版本基线,后续所有编译运行都基于它:
java -version
mvn -version | 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。
二、前置条件
在开始安装前,请确认以下条件满足,否则后续步骤会因权限或网络问题中断。
- root 权限或 sudo:安装 JDK、Maven 与写入
/opt目录需要相应权限。 - 网络可达:需要访问
downloads.apache.org(官方二进制包)与repo1.maven.org(Maven 中央仓库);网络连通性将在 4.3 的依赖下载与 5.2 的官方包下载时随实际命令自然验证。 - 磁盘空间:官方二进制包约 1.5 MB,加上本地 Maven 仓库缓存建议预留 ≥ 200 MB。
- JDK 版本:JCL 1.4.0 官方要求 Java 8 或更高(jar 内 class 文件 major 52,实测
javap确认);本文示例工程按 release 17 编译,因此需 JDK 17。 - 纯 Java 库:JCL 无本地原生依赖,x86_64 之外的架构同样可用。
⚠️ 注意:若内网无法直连上述域名,需按企业代理配置放行,否则 Maven 依赖与官方包均无法获取。本文实测环境为直连。
三、版本选型说明
Apache Commons Logging 是 Apache 基金会的经典日志门面(logging facade):它自身不写日志文件,而是通过 LogFactory.getLog(name) 在运行期探测 classpath 上可用的日志系统(java.util.logging、Log4j、SLF4J、Log4j2 API 等),把统一的 Log 接口桥接到实际实现上。它被 Spring 3.x 与众多老牌 Commons 组件(如 commons-jexl3)作为内置依赖广泛携带。
💡 技术拓展:「日志门面」不止 JCL 一种,选型前应了解 Java 生态四大主流门面/入口的定位差异——
名称 定位 绑定方式 特点与适用场景 Apache Commons Logging(JCL) 运行期发现的老牌门面 LogFactory运行时探测 classpath(1.4.0 起含 ServiceLoader 与 Log4j2/SLF4J 工厂候选)零传递依赖、单个 jar;存量 Commons/Spring 组件默认携带;新项目更推荐 SLF4J SLF4J 当前事实标准的门面 编译期绑定(slf4j-api + 一个 binding jar) 参数化消息、生态主流;绑定关系清晰可预期 JUL(java.util.logging) JDK 自带实现 无需任何依赖 简单工具与无依赖场景首选;JCL 1.4.0 单 jar 默认落点 Log4j2 API(log4j-api) 可直接当门面使用的 API log4j-api + log4j-core 性能强、支持 lambda 惰性求值;与 Log4j2 生态配套 本文以 JCL 1.4.0 为安装对象:它是本文库系列组件(如 commons-jexl3)的公共底层依赖,且 1.4.0 新增了到 Log4j2 API 与 SLF4J 的桥接工厂,存量项目可借此平滑汇入主流日志栈。
3.1 版本对照表
JCL 的版本序列有一个突出特征:1.2(2014-07)与 1.3.0(2023-11)之间存在近 9 年的断代。实测从 Maven 中央仓库元数据与 Apache 归档目录汇总的版本对照如下:
| 版本 | 发布日期 | 最低 Java | class 文件 major | 获取渠道 | 说明 |
|---|---|---|---|---|---|
| 1.2 | 2014-07-09 | Java 1.2 | 46(实测 javap 确认) | 仅 archive.apache.org | 断代前最后版本,存量项目主力版本 |
| 1.3.0 | 2023-11-30 | Java 8 | 52 | 仅 archive.apache.org | 断代后首个版本,改用 Java 8 基线 |
| 1.3.1 ~ 1.3.6 | 2024-03 ~ 2026-03 | Java 8 | 52 | 新版仅在 archive.apache.org | 1.3.x 共 7 个版本 |
| 1.4.0 | 2026-06-17 | Java 8 | 52(实测 javap 确认) | downloads.apache.org 与 Maven 均可 | 当前 latest/release,本文安装版本 |
💡 说明:
downloads.apache.org只保留最新 1.4.0;1.3.x 与 1.2 需从https://archive.apache.org/dist/commons/logging/binaries/获取。1.2 的 class major 46 意味着它几乎可在任何 JVM 上运行,这正是大量老系统仍锁在 1.2 的原因。
查询中央仓库全序列的实测命令与回显(latest/release 均为 1.4.0):
curl -s https://repo1.maven.org/maven2/commons-logging/commons-logging/maven-metadata.xml
<?xml version="1.0" encoding="UTF-8"?>
<metadata modelVersion="1.1.0">
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<versioning>
<latest>1.4.0</latest>
<release>1.4.0</release>
<versions>
<version>1.0</version>
<version>1.0.1</version>
<version>1.0.2</version>
<version>1.0.3</version>
<version>1.0.4</version>
<version>1.1</version>
<version>1.1.1</version>
<version>1.1.2</version>
<version>1.1.3</version>
<version>1.2</version>
<version>1.3.0</version>
<version>1.3.1</version>
<version>1.3.2</version>
<version>1.3.3</version>
<version>1.3.4</version>
<version>1.3.5</version>
<version>1.3.6</version>
<version>1.4.0</version>
</versions>
<lastUpdated>20260617133534</lastUpdated>
</versioning>
</metadata>
3.2 Maven 坐标陷阱(必读)
JCL 的 Maven groupId 是老的 commons-logging,而不是 org.apache.commons。与其他 Commons 组件(如 org.apache.commons:commons-lang3)相反,JCL 从未迁移到新 groupId。实测两条 URL 的 HTTP 状态码对比:
curl -s -o /dev/null -w "%{http_code}\n" --max-time 30 https://repo1.maven.org/maven2/org/apache/commons/commons-logging/maven-metadata.xml
curl -s -o /dev/null -w "%{http_code}\n" --max-time 30 https://repo1.maven.org/maven2/commons-logging/commons-logging/maven-metadata.xml
404
200
结论:依赖坐标必须写 commons-logging:commons-logging:1.4.0;写成 org.apache.commons:commons-logging 会让 Maven 报无法解析依赖。这是安装 JCL 时最常见的第一坑。
3.3 最低 Java 要求实证
1.4.0 官方 pom 明确要求 Java 1.8(commons.logging.javaversion=1.8,animal-sniffer 签名 java18)。用 javap 读 class 文件版本号的实测:
javap -v -cp /root/.m2/repository/commons-logging/commons-logging/1.4.0/commons-logging-1.4.0.jar org.apache.commons.logging.LogFactory 2>/dev/null | grep -E "major|minor"
javap -v -cp /opt/logging-jars/commons-logging-1.2.jar org.apache.commons.logging.LogFactory 2>/dev/null | grep -E "major|minor"
minor version: 0
major version: 52
minor version: 0
major version: 46
解读:1.4.0 为 major 52(Java 8),1.2 为 major 46(Java 1.2)。1.4.0 的 jar 在 Java 8 上可直接加载运行,而按 release 17 编译的业务代码则需要 JDK 17 运行时(多 JDK 并存时的坑见 9.2 的 FAQ Q2)。
3.4 官方下载目录现状
downloads.apache.org 的 binaries 目录当前只保留 1.4.0(含 tar.gz/zip 两种格式与 .asc 签名、.sha512 校验文件):
curl -s https://downloads.apache.org/commons/logging/binaries/
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<title>Index of /commons/logging/binaries</title>
</head>
<body>
<h2>Apache Commons Project Distributions</h2>
<p>The most recent source and binary releases for the Apache Commons project are available from this directory listing. For older releases, please use the <a href="http://archive.apache.org/dist/commons/">archives</a>. </p>
<h2>Important Notices</h2>
<ul>
<li><a href="#mirrors">Download from your nearest mirror site!</a></li>
<li><a href="#sig">PGP/GPG Signatures</a></li>
</ul>
<pre><img src="/icons/blank.gif" alt="Icon "> <a href="?C=N;O=D">Name</a> <a href="?C=M;O=A">Last modified</a> <a href="?C=S;O=A">Size</a> <a href="?C=D;O=A">Description</a><hr><img src="/icons/back.gif" alt="[PARENTDIR]"> <a href="/commons/logging/">Parent Directory</a> -
<img src="/icons/compressed.gif" alt="[ ]"> <a href="commons-logging-1.4.0-bin.tar.gz">commons-logging-1.4.0-bin.tar.gz</a> 2026-06-17 13:36 1.5M
<img src="/icons/text.gif" alt="[TXT]"> <a href="commons-logging-1.4.0-bin.tar.gz.asc">commons-logging-1.4.0-bin.tar.gz.asc</a> 2026-06-17 13:36 265
<img src="/icons/text.gif" alt="[TXT]"> <a href="commons-logging-1.4.0-bin.tar.gz.sha512">commons-logging-1.4.0-bin.tar.gz.sha512</a> 2026-06-17 13:36 129
<img src="/icons/compressed.gif" alt="[ ]"> <a href="commons-logging-1.4.0-bin.zip">commons-logging-1.4.0-bin.zip</a> 2026-06-17 13:36 1.6M
<img src="/icons/text.gif" alt="[TXT]"> <a href="commons-logging-1.4.0-bin.zip.asc">commons-logging-1.4.0-bin.zip.asc</a> 2026-06-17 13:36 265
<img src="/icons/text.gif" alt="[TXT]"> <a href="commons-logging-1.4.0-bin.zip.sha512">commons-logging-1.4.0-bin.zip.sha512</a> 2026-06-17 13:36 129
<hr></pre>
<h1>Commons-Logging v1.4.0</h1>
(后接官方下载说明 HTML;1.2 及更早版本只在 archive.apache.org 可得)
</body></html>
四、方案 A:Maven 在线依赖安装
官方推荐方式:通过 Maven 引入 commons-logging:commons-logging:1.4.0,由构建工具自动下载 jar。适合可联网的开发/构建环境,也是绝大多数业务项目的方式。
4.1 方案说明与适用场景
本方案创建一个最小 Maven 工程引入 JCL 1.4.0,编译并运行一个真实日志程序完成验证。适合持续集成、可访问中央仓库的场景。JCL 零传递依赖,引入后依赖树只有它自己一个 jar。
4.2 安装 JDK 17 与 Maven
Ubuntu 22.04 官方源提供 openjdk-17-jdk、maven 与 curl 包。若系统尚未安装,执行:
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y openjdk-17-jdk maven curl
本文实测环境两项均已就绪,安装后(或已预装时)用 1.1 节同款命令验证:
java -version
mvn -version | 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
验证点:mvn -version 的 Java version 为 17.0.20.1,说明 Maven 已绑定 JDK 17,可继续。
4.3 创建 Maven 工程并引入依赖
创建工程目录:
mkdir -p /opt/logging-demo/src/main/java/demo
/opt/logging-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>logging-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>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.4.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<release>17</release>
</configuration>
</plugin>
</plugins>
</build>
</project>
逐项说明:
groupId为commons-logging:沿用老坐标(见 3.2 坐标陷阱),切勿改成org.apache.commons。maven.compiler.release=17:用 JDK 17 的跨版本编译语义产出 release 17 字节码(JCL 1.4.0 在 JDK 17 上实测正常)。dependencies:仅声明commons-logging:1.4.0一项;JCL 没有任何传递依赖,无需其他条目。maven-compiler-plugin显式固定 3.11.0 并配置<release>17</release>,避免旧默认插件忽略 release 参数。
4.4 编写最小验证程序
/opt/logging-demo/src/main/java/demo/Demo.java 全文(后续 4.7 运行、第七章配置验证均复用该程序):
package demo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Demo {
public static void main(String[] args) {
Log log = LogFactory.getLog("demo");
System.out.println("log impl class = " + log.getClass().getName());
System.out.println("isTraceEnabled=" + log.isTraceEnabled()
+ " isDebugEnabled=" + log.isDebugEnabled()
+ " isInfoEnabled=" + log.isInfoEnabled()
+ " isWarnEnabled=" + log.isWarnEnabled()
+ " isErrorEnabled=" + log.isErrorEnabled()
+ " isFatalEnabled=" + log.isFatalEnabled());
log.trace("trace-msg");
log.debug("debug-msg");
log.info("info-msg");
log.warn("warn-msg");
log.error("error-msg");
log.fatal("fatal-msg");
System.out.println("done.");
}
}
程序行为说明:先打印实际绑定的 Log 实现类名与六个 isXxxEnabled 开关状态,再依次输出 trace/debug/info/warn/error/fatal 六个级别的日志,最后打印 done.。通过对比不同配置下的输出即可验证绑定与级别行为。
4.5 编译
静默模式编译(-q 只在出错时输出,成功时零输出,用退出码判断):
cd /opt/logging-demo && mvn -q compile; echo "exit=$?"
exit=0
非静默复核(首次执行会联网下载依赖,耗时略长;以下为依赖就绪后的回显):
cd /opt/logging-demo && mvn -B compile 2>&1 | tail -8
[INFO] --- maven-compiler-plugin:3.11.0:compile (default-compile) @ logging-demo ---
[INFO] Nothing to compile - all classes are up to date
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.460 s
[INFO] Finished at: 2026-10-14T15:11:19Z
[INFO] ------------------------------------------------------------------------
验证点:BUILD SUCCESS 且无编译错误,说明依赖解析与编译均正常。
4.6 依赖树验证:零传递依赖
cd /opt/logging-demo && mvn -B dependency:tree 2>&1 | sed -n "/--- maven-dependency-plugin:2.8:tree/,/--------</p"
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ logging-demo ---
[INFO] demo:logging-demo:jar:1.0.0
[INFO] \- commons-logging:commons-logging:jar:1.4.0:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.793 s
[INFO] Finished at: 2026-10-14T15:14:46Z
[INFO] ------------------------------------------------------------------------
再导出运行时 classpath 并查看内容:
cd /opt/logging-demo && mvn -B dependency:build-classpath -Dmdep.outputFile=/opt/logging-demo/cp.txt 2>&1 | tail -2 && echo "--- cp.txt:" && cat /opt/logging-demo/cp.txt
[INFO] Finished at: 2026-10-14T15:14:53Z
[INFO] ------------------------------------------------------------------------
--- cp.txt:
/root/.m2/repository/commons-logging/commons-logging/1.4.0/commons-logging-1.4.0.jar
解读:依赖树与 classpath 都证明 JCL 1.4.0 零传递依赖——运行时 classpath 只需它一个 jar。这也是它被海量组件携带而不拖累依赖树的原因。
4.7 运行验证
cd /opt/logging-demo && java -cp target/classes:$(cat cp.txt) demo.Demo
log impl class = org.apache.commons.logging.impl.Jdk14Logger
isTraceEnabled=false isDebugEnabled=false isInfoEnabled=true isWarnEnabled=true isErrorEnabled=true isFatalEnabled=true
Oct 14, 2026 3:15:17 PM demo main
INFO: info-msg
Oct 14, 2026 3:15:17 PM demo main
WARNING: warn-msg
Oct 14, 2026 3:15:17 PM demo main
SEVERE: error-msg
done.
Oct 14, 2026 3:15:17 PM demo main
SEVERE: fatal-msg
输出解读:
- 首行
log impl class = org.apache.commons.logging.impl.Jdk14Logger:单 jar 场景下默认绑定 Jdk14Logger,即桥接到 JDK 自带的 java.util.logging(JUL)。 isTraceEnabled=false isDebugEnabled=false:JUL 根 Logger 默认级别 INFO,trace/debug 被级别门槛挡掉;info/warn/error/fatal 开关均为 true。INFO: info-msg、WARNING: warn-msg、SEVERE: error-msg、SEVERE: fatal-msg:JCL 六级到 JUL 五级的映射为 trace→FINEST、debug→FINE、info→INFO、warn→WARNING、error/fatal→SEVERE(error 与 fatal 同级,均输出)。done.与 fatal 行交错:JUL 日志走 stderr、System.out走 stdout,两条流混排所致,属正常现象。