Ubuntu 22.04 安装 Apache Commons Logging 指南

在 Ubuntu 22.04 上从零引入 Apache Commons Logging 1.4.0,覆盖 Maven 坐标陷阱、Maven 依赖与官方二进制包两套安装方案、JUL 基础配置与升级降级管理,附真实回显与 UnsupportedClassVersionError 排障。

Apache Commons LoggingApache Commons Logging2026/10/15

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。

二、前置条件

在开始安装前,请确认以下条件满足,否则后续步骤会因权限或网络问题中断。

  1. root 权限或 sudo:安装 JDK、Maven 与写入 /opt 目录需要相应权限。
  2. 网络可达:需要访问 downloads.apache.org(官方二进制包)与 repo1.maven.org(Maven 中央仓库);网络连通性将在 4.3 的依赖下载与 5.2 的官方包下载时随实际命令自然验证。
  3. 磁盘空间:官方二进制包约 1.5 MB,加上本地 Maven 仓库缓存建议预留 ≥ 200 MB。
  4. JDK 版本:JCL 1.4.0 官方要求 Java 8 或更高(jar 内 class 文件 major 52,实测 javap 确认);本文示例工程按 release 17 编译,因此需 JDK 17。
  5. 纯 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)可直接当门面使用的 APIlog4j-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 归档目录汇总的版本对照如下:

版本发布日期最低 Javaclass 文件 major获取渠道说明
1.22014-07-09Java 1.246(实测 javap 确认)仅 archive.apache.org断代前最后版本,存量项目主力版本
1.3.02023-11-30Java 852仅 archive.apache.org断代后首个版本,改用 Java 8 基线
1.3.1 ~ 1.3.62024-03 ~ 2026-03Java 852新版仅在 archive.apache.org1.3.x 共 7 个版本
1.4.02026-06-17Java 852(实测 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,两条流混排所致,属正常现象。