Java/Spark 项目报错:NoClassDefFoundError 的成因与解决方案


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 手动指定依赖路径

文章作者: QT
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 QT !
赏
 上一篇
sshd 服务与 SFTP 子系统稳定性配置指南 sshd 服务与 SFTP 子系统稳定性配置指南
本文总结在 JetBrains Gateway、SCP/SFTP 远程开发与传输中遇到的 sshd 子系统超时、权限异常、非交互输出等问题,并提供一套安全稳定的配置方案。
下一篇 
Spark 高可用部署中的路径扩容与软链接技巧 Spark 高可用部署中的路径扩容与软链接技巧
Spark 的 work 目录默认位于安装目录下,这在高并发环境中容易造成空间瓶颈。本文介绍了两种路径迁移方法:修改 spark-env.sh 和使用软链接,并分析了各自的优劣。
  目录