You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spark Java代码Eclipse运行正常,Maven打包后执行Jar报ClassNotFoundException

解决Spark连接NATS时ClassNotFoundException问题

问题根源

  1. Spring Boot可执行Jar的类加载隔离:当使用java -jar运行Spring Boot打包的可执行Jar时,JVM会忽略-cp参数指定的外部类路径,转而使用Spring Boot自带的LaunchedURLClassLoader,仅加载Jar内部BOOT-INF/lib目录下的依赖,你通过-cp指定的NATS相关Jar不会被加载。
  2. spark.jars参数的适用场景:这个配置是为Spark集群模式设计的,用于将Jar分发到集群节点;本地模式下,Spark会尝试从指定路径加载Jar,但路径如果是相对路径,可能与运行命令的工作目录不匹配,且Spark的类加载器无法访问Spring Boot类加载器之外的外部Jar。

解决方案

方案一:将NATS依赖打包到Spring Boot可执行Jar中(推荐)

这个方法能彻底避免类加载隔离问题,步骤如下:

  1. 将NATS本地Jar安装到本地Maven仓库
    执行以下命令,把libs目录下的两个Jar安装到本地仓库:
    mvn install:install-file -Dfile=libs/nats-spark-connector-balanced_2.12-1.1.4.jar -DgroupId=external.group -DartifactId=nats-spark-connector-balanced_2.12 -Dversion=1.1.4 -Dpackaging=jar
    mvn install:install-file -Dfile=libs/jnats-2.17.1.jar -DgroupId=external.group -DartifactId=jnats -Dversion=2.17.1 -Dpackaging=jar
    
  2. 修改pom.xml依赖配置
    取消之前注释的NATS依赖,移除system作用域和systemPath,改为普通依赖:
    <dependency>
        <groupId>external.group</groupId>
        <artifactId>nats-spark-connector-balanced_2.12</artifactId>
        <version>1.1.4</version>
    </dependency>
    <dependency>
        <groupId>external.group</groupId>
        <artifactId>jnats</artifactId>
        <version>2.17.1</version>
    </dependency>
    
  3. 重新打包并运行
    执行打包命令:
    mvn clean package
    
    运行生成的可执行Jar:
    java -jar spark-learning-0.0.1-SNAPSHOT.jar
    

方案二:打包为普通Jar,通过-cp指定全量类路径

如果不想将NATS依赖打包到可执行Jar中,可以修改打包方式:

  1. 修改pom.xml的打包配置
    移除spring-boot-maven-plugin的repackage执行目标,或者改用普通Maven打包插件,确保生成的是普通Jar而非Spring Boot可执行Jar。
  2. 运行时指定完整类路径
    运行时将所有依赖(Spark、NATS、自身Jar)都加入类路径:
    # Linux/macOS
    java -cp "../libs/*.jar:spark-learning-0.0.1-SNAPSHOT.jar" com.test.MinIOTester
    # Windows
    java -cp "../libs/*.jar;spark-learning-0.0.1-SNAPSHOT.jar" com.test.MinIOTester
    

方案三:调整SparkSession配置,指定本地Jar路径

如果坚持使用外部Jar,需要修改SparkSession配置,让Spark的类加载器能找到Jar:

SparkSession spark = SparkSession.builder()
        .appName("spark-with-nats")
        .master("local")
        // 指定驱动端额外类路径,本地模式生效
        .config("spark.driver.extraClassPath", "../libs/nats-spark-connector-balanced_2.12-1.1.4.jar:../libs/jnats-2.17.1.jar")
        .config("spark.sql.streaming.checkpointLocation","tmp/checkpoint")
        .config("spark.sql.extensions", "io.delta.sql.DeltaSparkSessionExtension")
        .config("spark.sql.catalog.spark_catalog", "org.apache.spark.sql.delta.catalog.DeltaCatalog")
        .getOrCreate();

注意:Windows系统下路径分隔符使用分号;,且路径要确保与运行命令的工作目录匹配。

内容的提问来源于stack exchange,提问作者VGH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 18:47:34