1. 错误现象
在运行 Java 或 Spark 应用时,控制台出现如下报错:
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/ConsoleAppender
...
Caused by: java.lang.ClassNotFoundException: org.apache.log4j.ConsoleAppender
该错误阻止了程序运行,常见于:
- 运行 jar 包时使用
java -jar或spark-submit - 程序引用了 log4j 日志库,但 jar 包未包含或未加载
2. 错误分析
这个报错由两层含义组成:
NoClassDefFoundError
程序在运行时找不到某个类的定义,通常是 classpath 中缺少某个 jar 包。
ClassNotFoundException
JVM 尝试加载一个类时失败,可能是因为 jar 文件根本没被传入运行时环境中。
结合错误栈可知,缺失类为:
org.apache.log4j.ConsoleAppender
这是 log4j-1.2.x 版本中用于输出控制台日志的类。
3. 常见场景
场景 1:使用 java -jar 启动应用
如果 log4j 未打包进主 jar 或未显式引入:
java -jar your-app.jar # 会找不到 log4j
场景 2:使用 spark-submit 启动 Spark 程序
spark-submit --class Main your-app.jar
此时需要显式通过 --jars 添加依赖。
4. 解决方案
✅ 方法一:手动引入 log4j jar 包
从官方或 Maven 仓库下载:
wget https://repo1.maven.org/maven2/log4j/log4j/1.2.17/log4j-1.2.17.jar -P lib/
运行时通过 -cp 或 --jars 添加:
java -cp your-app.jar:lib/log4j-1.2.17.jar MainClass
或 Spark 中:
spark-submit --class MainClass \
--jars lib/log4j-1.2.17.jar \
your-app.jar
✅ 方法二:打包时将依赖合并进 jar(推荐)
Maven 项目示例
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
构建命令:
mvn clean package assembly:single
生成的 your-app-jar-with-dependencies.jar 包含所有依赖。
✅ 方法三:Gradle 项目添加 log4j 依赖
dependencies {
implementation 'log4j:log4j:1.2.17'
}
并使用 shadowJar 插件进行打包。
5. 附加提示:排查 classpath 内容
使用以下命令查看当前运行是否包含 log4j:
java -verbose:class -cp your.jar MainClass
观察是否有 log4j 的路径加载记录。如果没有说明 classpath 缺失。
6. 总结
| 问题 | 原因 | 解决方法 |
|---|---|---|
| NoClassDefFoundError | 缺失 log4j 类 | 添加 jar 或合并打包 |
| Spark 项目失败 | 未传入依赖 | 使用 --jars 或 Maven 打包 |
| Java 运行失败 | java -jar 默认不加载外部依赖 |
用 -cp 手动指定依赖路径 |