Ubuntu 22.04 安装 Apache Chainsaw 指南

在 Ubuntu 22.04 上从零安装并验证 Apache Chainsaw 2.1.0 日志分析工具的全流程实录,涵盖 standalone 官方包安装、源码 Maven 构建、无显示器环境下 xvfb 虚拟帧缓冲的 GUI 验证与常见问题排障。

Apache ChainsawApache Chainsaw2026/10/15

Ubuntu 22.04 安装 Apache Chainsaw 指南

目标:在一台 Ubuntu 22.04 服务器上完成 Apache Chainsaw 2.1.0 的下载、安装、启动配置与验证,包括无显示器环境下借助 X 虚拟帧缓冲(xvfb)完成的图形界面真实启动验证,以及不依赖图形界面的 headless 接收器验证。(以下全部命令与回显均来自真实环境实测)

Apache Chainsaw 是 Log4j 生态下的开源日志查看与分析工具(Swing 桌面程序),支持按格式模板解析文本日志文件、通过 UDP/组播/TCP 接收网络日志事件,并内置过滤表达式、颜色规则、事件收藏等分析功能。与常规后端服务不同,Chainsaw 是图形界面程序,安装后"能不能跑"必须通过图形栈验证;在无显示器的服务器上,需要用 xvfb 模拟一块虚拟显示。本文按 0→1 全流程记录每一步的真实命令与回显。

一、环境信息

本文实测所用服务器软硬件信息如下:

项目值
操作系统Ubuntu 22.04.5 LTS(x86_64)
Java 环境OpenJDK 17.0.20.1(apt 仓库 openjdk-17-jdk)
Chainsaw 版本2.1.0(2021-06-12 发布,官方当前唯一版本)
安装目录/opt/apache-chainsaw-2.1.0
实验目录/opt/chainsaw-headless
图形栈Xvfb(虚拟帧缓冲)+ x11-utils(xwininfo/xdpyinfo)

操作系统与基础环境确认:

cat /etc/os-release | head -3

实测回显:

PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
uname -m

实测回显:

x86_64

二、前置条件

  1. 具备 root 权限或 sudo 免密(安装 JDK、Xvfb 与写 /opt 目录均需要)。
  2. 服务器可访问 downloads.apache.org(下载官方包)。连通性探测:
curl -sI --max-time 20 https://downloads.apache.org/logging/chainsaw/2.1.0/apache-chainsaw-2.1.0-standalone.tar.gz | head -5

实测回显:

HTTP/1.1 200 OK
Date: Thu, 15 Oct 2026 08:05:34 GMT
Server: Apache
Last-Modified: Sat, 12 Jun 2021 14:20:08 GMT
ETag: "2cf6e2-5c4925249ea69"
  1. Java 运行时版本要求:JDK 9 及以上。实测依据:官方 jar 的字节码主版本号为 53(Java 9+),主类 MANIFEST 中 Build-Jdk-Spec 为 11(验证方法见第八章)。推荐安装 OpenJDK 11 或 17,本文使用 17:
apt-get install -y openjdk-17-jdk

实测回显(首次安装时会出现下载与解包进度;若已装过则显示如下):

openjdk-17-jdk is already the newest version (17.0.20.1+1-1~22.04).
0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded.
java -version

实测回显:

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)
  1. 图形栈组件:无显示器的服务器需要 X 虚拟帧缓冲(xvfb)与 x11-utils(提供 xdpyinfo、xwininfo 用于验证):
apt-get install -y xvfb x11-utils

实测回显:

xvfb is already the newest version (2:21.1.4-2ubuntu1.7~22.04.16).
x11-utils is already the newest version (7.7+5build2).
  1. 磁盘空间约 100 MB(standalone 包 2.9 MB,解压后约 20 MB,加上源码构建缓存预留)。

三、版本选型说明

3.1 官方版本与发布渠道

官方下载目录 https://downloads.apache.org/logging/chainsaw/ 实测仅有 2.1.0 一个版本目录(2021-06-12 发布),包含 bin、standalone、src 三类包及对应的 .sha512 校验文件。本文全部实测基于 2.1.0。

一个重要的实测事实:Chainsaw 2.1.0 没有发布到 Maven Central。以下三个候选坐标在 Maven Central 中实测均不存在(HTTP 404):org.apache.logging.chainsaw:chainsaw、log4j:chainsaw、log4j:apache-chainsaw。因此无法通过 Maven 依赖坐标引入 Chainsaw,只能使用官方二进制包或从源码构建(源码包内 pom.xml 的坐标为 log4j:apache-chainsaw:2.1.0)。

另一个实测事实:Chainsaw 2.1.0 基于 log4j 1.x 生态而非 log4j2。standalone 包内嵌依赖仓库 repo/ 中是 log4j-1.2.16.jar 与 apache-log4j-extras-1.1.jar,根目录平铺 jar 亦同。也就是说,Chainsaw 自带完整的 log4j 1.2.16 运行时与扩展接收器(LogFilePatternReceiver、UDPReceiver 等都在主 jar 内),无需另配依赖。

3.2 三种官方包的差异(实测解包结论)

包名大小内容适用场景
apache-chainsaw-2.1.0-standalone.tar.gz2.9 MBbin/chainsaw 启动脚本、bin/chainsaw.bat、repo/ 内嵌依赖仓库、根目录平铺 jar、src、site服务器直接安装运行(官方推荐)
apache-chainsaw-2.1.0-bin.tar.gz6.0 MB根目录平铺 jar、src、site、pom.xml、build.xml;无启动脚本、无 repo/研究源码/二次开发
apache-chainsaw-2.1.0-src.tar.gz2.1 MB纯源码 + pom.xml + build.xml源码构建

💡 技术拓展:日志查看/分析工具选型对比

工具形态定位适用场景
Apache ChainsawSwing GUIlog4j 1.x 生态的本地日志接收与交互分析(接收器+过滤+着色)服务器日志文件解析、网络事件实时分析、无中心化部署
Apache Log4j2 自带 GUI无独立工具log4j2 生态下需自研或借助第三方log4j2 项目配套
tail/grep/awk命令行快速检索、即时性强单文件简单查询,无结构化解析
KibanaWeb 平台ELK 集中式的检索与仪表盘已建 ELK/EFK 体系的中大型环境
LogExpert/BareTailWindows GUI本地文件追尾查看Windows 工作站轻量场景

本文与整个专栏采用 Apache Chainsaw:它可以在不引入任何中心化组件的前提下,直接解析日志文件或接收 UDP/组播事件,在服务器上配合 xvfb 即可完成全部 GUI 功能验证。

四、方案 A:官方 standalone 包安装(推荐)

4.1 下载与完整性校验

cd /root
curl -sO https://downloads.apache.org/logging/chainsaw/2.1.0/apache-chainsaw-2.1.0-standalone.tar.gz
curl -sO https://downloads.apache.org/logging/chainsaw/2.1.0/apache-chainsaw-2.1.0-standalone.tar.gz.sha512

用官方 sha512 与本地文件比对:

sha512sum apache-chainsaw-2.1.0-standalone.tar.gz

实测回显:

1e2131c9e490551b5ec2ed4a9f9885bb28791b8f28585b6d70285e68985238da1c166cb84aac4a9b9d9acfa72e184b268bd1540875aad3de525a65acaf4ef926  apache-chainsaw-2.1.0-standalone.tar.gz

与 .sha512 文件内容一致,校验通过。

4.2 解压安装到 /opt

tar xzf apache-chainsaw-2.1.0-standalone.tar.gz -C /opt/
ls /opt/apache-chainsaw-2.1.0/

实测回显:

LICENSE
NOTICE
apache-chainsaw-2.1.0.jar
apache-log4j-extras-1.1.jar
bin
build.xml
commons-logging-1.1.1.jar
commons-vfs-1.0.jar
jmdns-3.4.1.jar
jsch-0.1.55.jar
log4j-1.2.16.jar
pom.xml
repo
site
src
xmlpull-1.1.3.1.jar
xpp3_min-1.1.4c.jar
xstream-1.4.11.1.jar

4.3 启动脚本与 JVM 参数位置

启动脚本为 /opt/apache-chainsaw-2.1.0/bin/chainsaw(对应 Windows 的 bin/chainsaw.bat),关键行为(阅读脚本得到的结论):

  • 默认 JAVA_HOME 未设置时直接使用 PATH 中的 java;可用 JAVA_HOME 环境变量指定 JVM。
  • classpath 优先取 $BASEDIR/repo 下的内嵌仓库(Maven 布局 jar),主类为 org.apache.log4j.chainsaw.LogUI(主 jar MANIFEST 中 Main-Class 实测一致)。
  • JVM 参数通过 JAVA_OPTS 环境变量传入,脚本会把它拼在 java 命令之后——这就是修改堆大小的位置。官方脚本未预设堆参数,JVM 走默认值(通常为物理内存的 1/4);生产建议显式设置。

主 jar MANIFEST 关键字段(实测):

Implementation-Version: 2.1.0
Main-Class: org.apache.log4j.chainsaw.LogUI
Build-Jdk-Spec: 11

内嵌依赖仓库(实测清单):

/opt/apache-chainsaw-2.1.0/repo/com/jcraft/jsch/0.1.55/jsch-0.1.55.jar
/opt/apache-chainsaw-2.1.0/repo/com/thoughtworks/xstream/xstream/1.4.11.1/xstream-1.4.11.1.jar
/opt/apache-chainsaw-2.1.0/repo/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar
/opt/apache-chainsaw-2.1.0/repo/commons-vfs/commons-vfs/1.0/commons-vfs-1.0.jar
/opt/apache-chainsaw-2.1.0/repo/javax/jmdns/jmdns/3.4.1/jmdns-3.4.1.jar
/opt/apache-chainsaw-2.1.0/repo/log4j/apache-chainsaw/2.1.0/apache-chainsaw-2.1.0.jar
/opt/apache-chainsaw-2.1.0/repo/log4j/apache-log4j-extras/1.1/apache-log4j-extras-1.1.jar
/opt/apache-chainsaw-2.1.0/repo/log4j/log4j/1.2.16/log4j-1.2.16.jar
/opt/apache-chainsaw-2.1.0/repo/xmlpull/xmlpull/1.1.3.1/xmlpull-1.1.3.1.jar
/opt/apache-chainsaw-2.1.0/repo/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.jar

要点小结:standalone 包自含全部依赖,解压即可运行;JVM 参数位置就是 bin/chainsaw 读到的 JAVA_OPTS 环境变量。

五、方案 B:源码 Maven 构建与 jar 直跑

5.1 适用场景

无法直接下载二进制包但能拉取源码,或需要修改源码时,用源码构建。源码包同样来自官方下载目录。

5.2 下载与解压

cd /root
curl -sO https://downloads.apache.org/logging/chainsaw/2.1.0/apache-chainsaw-2.1.0-src.tar.gz
mkdir -p /root/chainsaw-src && tar xzf apache-chainsaw-2.1.0-src.tar.gz -C /root/chainsaw-src
ls /root/chainsaw-src | head -8

实测回显(前 8 项):

HOWTOBUILD.txt
LICENSE
NOTICE
build.xml
pom.xml
site
src
xdocs

5.3 Maven 构建(JDK 17 需追加模块开放参数)

源码包 pom.xml 中 maven.compiler.source 为 1.8,依赖 lombok 1.18.0。在 JDK 17 上直接 mvn package 会因强封装失败,实测报错:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project apache-chainsaw: Fatal error compiling: java.lang.ExceptionInInitializerError: Unable to make field private com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors com.sun.tools.javac.processing.JavacProcessingEnvironment.discoveredProcs accessible: module jdk.compiler does not "opens com.sun.tools.javac.processing" to unnamed module @dbdaa1d -> [Help 1]

解法:给 Maven 的 JVM 追加 jdk.compiler 模块的 --add-opens(这就是本文实测成功的构建命令)。另外直接 mvn package 只出主 jar,assembly 打包阶段要求先有 site 产物,需加 site 目标。完整实测命令:

cd /root/chainsaw-src
export MAVEN_OPTS="--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED"
mvn -B site package -DskipTests -Dmaven.javadoc.skip=true -Drat.skip=true

实测回显(结尾):

[INFO] BUILD SUCCESS
[INFO] Total time:  13:21 min

构建产物(实测清单):

target/apache-chainsaw-2.1.0-bin.tar.gz
target/apache-chainsaw-2.1.0.jar
target/apache-chainsaw-2.1.0-sources.jar
target/apache-chainsaw-2.1.0-standalone.tar.gz

构建出的 standalone 包与官方包结构一致,可按第四章同样方式安装。

5.4 jar 直跑(不装 GUI 也能用)

standalone 包解压后的 repo 目录就是完整 classpath。不启动 GUI,直接用其中的 jar 编译/运行 headless 程序(解析日志文件示例,完整代码见第八章 8.3):

mkdir -p /opt/chainsaw-headless/classes
cd /opt/chainsaw-headless
javac -encoding UTF-8 -cp /opt/apache-chainsaw-2.1.0/repo/log4j/apache-chainsaw/2.1.0/apache-chainsaw-2.1.0.jar:/opt/apache-chainsaw-2.1.0/repo/log4j/apache-log4j-extras/1.1/apache-log4j-extras-1.1.jar:/opt/apache-chainsaw-2.1.0/repo/log4j/log4j/1.2.16/log4j-1.2.16.jar -d classes LogFilePatternReceiverDemo.java
java -Dfile.encoding=UTF-8 -cp classes:/opt/apache-chainsaw-2.1.0/repo/log4j/apache-chainsaw/2.1.0/apache-chainsaw-2.1.0.jar:/opt/apache-chainsaw-2.1.0/repo/log4j/apache-log4j-extras/1.1/apache-log4j-extras-1.1.jar:/opt/apache-chainsaw-2.1.0/repo/log4j/log4j/1.2.16/log4j-1.2.16.jar LogFilePatternReceiverDemo

实测回显(业务事件部分):

  EVENT level=INFO logger=com.example.service.OrderService thread=main msg=订单创建成功 orderId=1001
  EVENT level=WARN logger=com.example.service.InventoryService thread=main msg=库存低于阈值 sku=SKU-1024
  EVENT level=ERROR logger=com.example.service.PayService thread=main msg=支付网关超时 orderId=9001
业务事件总数=3

六、方案对比与选择建议

维度方案 A:standalone 官方包方案 B:源码构建 + jar 直跑
获取方式官网直接下载 2.9 MB 包下载 2.1 MB 源码包后 Maven 构建
安装耗时解压即完成(秒级)实测构建 13 分 21 秒
启动脚本自带 bin/chainsaw需自配 java -cp 命令或自行组装
版本一致性与官方发布完全一致受本机 JDK/Maven 影响较大
适用场景绝大多数服务器安装需改源码、内网无法直接下载二进制时

选择建议:优先方案 A;方案 B 用于无法获取二进制包或需定制源码的场景。两方案产物可共存于不同目录,互不影响。

七、基础配置

7.1 JVM 堆参数

Chainsaw 的 JVM 参数入口是 bin/chainsaw 读取的 JAVA_OPTS 环境变量。本文统一使用 256 MB 堆(日志分析负载不大时足够;若加载大日志文件可调至 512 MB)。写一个环境文件便于管理:

cat > /etc/profile.d/chainsaw.sh <<'EOF'
export CHAINSAW_HOME=/opt/apache-chainsaw-2.1.0
export JAVA_OPTS="-Xms256m -Xmx256m --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.base/java.time=ALL-UNNAMED --add-opens java.base/java.math=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.desktop/java.awt=ALL-UNNAMED --add-opens java.desktop/java.awt.font=ALL-UNNAMED"
EOF
source /etc/profile.d/chainsaw.sh

修改方法:直接编辑 /etc/profile.d/chainsaw.sh,把 -Xms256m -Xmx256m 调整为目标值(如 -Xms512m -Xmx512m),重新 source 或重新登录后生效。--add-opens 系列参数的作用见第九章 FAQ 第一条。

7.2 无显示器服务器的启动方式

Chainsaw 是 Swing 程序,无显示器的服务器需要 X 虚拟帧缓冲(xvfb)。启动 Xvfb 并在指定显示号上运行 Chainsaw:

Xvfb :97 -screen 0 1280x1024x24 >/tmp/xvfb97.log 2>&1 &
sleep 2
cd /opt/apache-chainsaw-2.1.0
DISPLAY=:97 nohup bin/chainsaw >/tmp/chainsaw-gui.log 2>&1 &

要点小结:Xvfb 先于 Chainsaw 启动;DISPLAY 指向 Xvfb 的显示号;两者都是普通前台/后台进程,重启服务器后需按此顺序重新拉起(可写入 systemd unit 或开机脚本)。

八、安装验证

8.1 GUI 真实启动验证(xvfb + xwininfo)

按 7.2 启动约 20 秒后,用 xwininfo 检查虚拟显示器上是否真的出现了 Chainsaw 的窗口(窗口 WM_CLASS 实测为 org-apache-log4j-chainsaw-LogUI):

DISPLAY=:97 xwininfo -root -tree | grep -iE "chainsaw" | head -4

实测回显:

     0x200166 "Pick a Color": ("org-apache-log4j-chainsaw-LogUI" "org-apache-log4j-chainsaw-LogUI")  523x343+379+341  +379+341
        0x20016e "Content window": ("org-apache-log4j-chainsaw-LogUI" "org-apache-log4j-chainsaw-LogUI")  523x343+0+0  +379+341
     0x200156 " ": ("org-apache-log4j-chainsaw-LogUI" "org-apache-log4j-chainsaw-LogUI")  644x516+0+0  +0+0
        0x20015e "Content window": ("org-apache-log4j-chainsaw-LogUI" "org-apache-log4j-chainsaw-LogUI")  644x516+0+0  +0+0

统计窗口数:

DISPLAY=:97 xwininfo -root -tree | grep -c "org-apache-log4j-chainsaw-LogUI"

实测回显:

33

进程确认:

jps -l | grep -v Jps

实测回显:

8052 org.apache.log4j.chainsaw.LogUI

Chainsaw 启动过程的控制台输出(/tmp/chainsaw-gui.log 实测,均为正常信息):

Security framework of XStream not initialized, XStream is probably vulnerable.
Using basic font
Wanting to add a row, but GUI not initialized, waiting...

进一步的可视化验证:在装了 ImageMagick 的机器上执行 DISPLAY=:97 import -window root /tmp/chainsaw-97.png 可对虚拟显示器截图。本文实测截图中可见 Chainsaw v2 完整主界面:菜单栏 File、View、Current tab、Connect to、Help;标签页 Welcome、ZeroConf、chainsaw-log;欢迎页标题 "Chainsaw v2 - brought to you by the Log4j Dev team";Hot Keys 面板(F3 Find Next、CMD-F Find、CMD-N New tab 等快捷键列表);接收器配置对话框(Use fileappender entries from a log4j config file、Process a log file、Receive events from the network、Use a Chainsaw config file 四个选项)。GUI 验证通过。

8.2 字节码版本验证(Java 9+ 依据)

javap -verbose -cp /opt/apache-chainsaw-2.1.0/repo/log4j/apache-chainsaw/2.1.0/apache-chainsaw-2.1.0.jar org.apache.log4j.chainsaw.LogUI | grep -E "major|minor"

实测回显:

  minor version: 0
  major version: 53

major 53 对应 Java 9。这就是本文把 JDK 版本要求定为 9+、推荐 11/17 的实测依据。

8.3 headless 功能验证(不依赖图形栈)

用 jar 直跑方式验证核心解析能力。示例程序把 LogFilePatternReceiver 解析出的日志事件路由到自定义 Appender 并回显:

cat > /opt/chainsaw-headless/demo-log/app.log <<'EOF'
2026-10-15 09:30:00,123 INFO com.example.service.OrderService 订单创建成功 orderId=1001
2026-10-15 09:30:01,456 WARN com.example.service.InventoryService 库存低于阈值 sku=SKU-1024
2026-10-15 09:30:02,789 ERROR com.example.service.PayService 支付网关超时 orderId=9001
EOF

Java 源码(/opt/chainsaw-headless/LogFilePatternReceiverDemo.java):

import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.varia.LogFilePatternReceiver;

public class LogFilePatternReceiverDemo {

    static int bizCount = 0;

    static class DumpAppender extends AppenderSkeleton {
        @Override
        protected void append(LoggingEvent e) {
            System.out.println("  EVENT level=" + e.getLevel()
                    + " logger=" + e.getLoggerName()
                    + " thread=" + e.getThreadName()
                    + " msg=" + e.getMessage());
            if (e.getLoggerName().startsWith("com.example")) {
                bizCount++;
            }
        }

        @Override
        public void close() {
        }

        @Override
        public boolean requiresLayout() {
            return false;
        }
    }

    public static void main(String[] args) throws Exception {
        Logger root = Logger.getRootLogger();
        root.setLevel(Level.INFO);
        root.addAppender(new DumpAppender());

        LogFilePatternReceiver receiver = new LogFilePatternReceiver();
        receiver.setName("demo-pattern-receiver");
        receiver.setFileURL("file:///opt/chainsaw-headless/demo-log/app.log");
        receiver.setLogFormat("TIMESTAMP LEVEL LOGGER MESSAGE");
        receiver.setTimestampFormat("yyyy-MM-dd HH:mm:ss,SSS");
        receiver.setTailing(false);
        receiver.setUseCurrentThread(true);
        receiver.setLoggerRepository(LogManager.getLoggerRepository());
        receiver.activateOptions();
        receiver.shutdown();
        System.out.println("业务事件总数=" + bizCount);
    }
}

编译运行命令与完整实测回显(见 5.4),此处列关键输出:

  EVENT level=INFO logger=org.apache.log4j.varia.LogFilePatternReceiver thread=main msg=activateOptions
  EVENT level=INFO logger=org.apache.log4j.varia.LogFilePatternReceiver thread=main msg=attempting to load file: file:///opt/chainsaw-headless/demo-log/app.log
  EVENT level=INFO logger=com.example.service.OrderService thread=main msg=订单创建成功 orderId=1001
  EVENT level=WARN logger=com.example.service.InventoryService thread=main msg=库存低于阈值 sku=SKU-1024
  EVENT level=ERROR logger=com.example.service.PayService thread=main msg=支付网关超时 orderId=9001
业务事件总数=3

三条业务日志全部按格式模板解析为结构化事件,中文消息无损。安装验证全部通过。

要点小结:GUI 侧用 xvfb+xwininfo 拿到窗口级证据;headless 侧用接收器 API 拿到解析级证据,两者共同确认安装可用。

九、常见问题(FAQ)

9.1 JDK 17 启动 GUI 报 InaccessibleObjectException 崩溃

现象:不带 --add-opens 直接启动,进程立刻退出,控制台实测报错(节选):

Exception in thread "main" java.lang.ExceptionInInitializerError
        at com.thoughtworks.xstream.XStream.setupConverters(XStream.java:990)
        at org.apache.log4j.chainsaw.ApplicationPreferenceModelSaver.loadSettings(ApplicationPreferenceModelSaver.java:53)
        at org.apache.log4j.chainsaw.prefs.SettingsManager.configure(SettingsManager.java:302)
        at org.apache.log4j.chainsaw.LogUI.main(LogUI.java:211)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.util.Comparator java.util.TreeMap.comparator accessible: module java.base does not "opens java.util" to unnamed module @4f51ab48

原因:Chainsaw 内嵌的 XStream 1.4.11.1 在 JDK 9+ 的模块强封装下无法反射 java.util 内部字段。解法:按 7.1 在 JAVA_OPTS 中加上文实测的 --add-opens 参数(java.base 的 util/lang/io/text/time/math/net/lang.reflect/util.concurrent 与 java.desktop 的 awt/awt.font),加齐后本文 GUI 启动验证一次通过。

9.2 JDK 8 报 UnsupportedClassVersionError

现象:用 JDK 8 运行 headless 演示,实测报错:

java.lang.UnsupportedClassVersionError: org/apache/log4j/varia/LogFilePatternReceiver has been compiled by a more recent version of the Java Runtime (class file version 53.0), this version of the Java Runtime only recognizes class file versions up to 52.0

原因:官方 jar 字节码为 major 53(Java 9+),JDK 8(52.0)无法加载。解法:升级到 JDK 11 或 17。

9.3 无显示器服务器 GUI 无法显示

现象:直接运行 bin/chainsaw 报 HeadlessException 或界面无法创建。解法:无显示器的服务器需要 X 虚拟帧缓冲(xvfb),先启动 Xvfb 再用 DISPLAY 环境变量指向它(见 7.2),本文在 :97 显示号上完成了全流程验证。

9.4 Maven 里搜不到 chainsaw 依赖

现象:在 pom 中引入 org.apache.logging.chainsaw:chainsaw 或 log4j:apache-chainsaw 报找不到构件。原因:Chainsaw 2.1.0 未发布到 Maven Central(实测三个候选坐标均 404)。解法:用官方 standalone 包,或下载源码包本地构建(见第五、六章)。

9.5 GUI 日志出现 Security framework of XStream not initialized

现象:启动日志持续出现 "Security framework of XStream not initialized, XStream is probably vulnerable."。原因:XStream 未配置安全框架时的常规告警。影响:本地单机分析工具,不监听网络端口,风险可控;如需消除可升级 XStream 或配置 XStream 安全白名单,属于进阶改造项。

十、卸载与清理

rm -rf /opt/apache-chainsaw-2.1.0
rm -rf /opt/chainsaw-headless
rm -f /etc/profile.d/chainsaw.sh
rm -f /root/apache-chainsaw-2.1.0-standalone.tar.gz /root/apache-chainsaw-2.1.0-standalone.tar.gz.sha512
rm -f /root/apache-chainsaw-2.1.0-src.tar.gz
rm -rf /root/chainsaw-src

如有不再使用的 Xvfb 实例,先停进程再按需卸载:

pkill -f "Xvfb :97"
apt-get remove -y xvfb x11-utils
apt-get autoremove -y

OpenJDK 17 如无其他应用使用,可一并卸载(卸载前确认没有其他服务依赖):

apt-get remove -y openjdk-17-jdk
apt-get autoremove -y

十一、参考链接