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

PySpark使用Spark MSSQL连接器BulkCopy时报NoSuchMethodError

问题背景

使用MS SQL connector for Spark从PySpark向SQL Server插入大批量数据时抛出方法不存在错误。

SparkSession初始化配置

SparkSession.builder
    .config('spark.jars.packages', 'org.apache.hadoop:hadoop-azure:3.2.0,org.apache.spark:spark-avro_2.12:3.1.2,com.microsoft.sqlserver:mssql-jdbc:8.4.1.jre8,com.microsoft.azure:spark-mssql-connector_2.12:1.2.0')

报错堆栈

ERROR executor.Executor: Exception in task 6.0 in stage 12.0 (TID 233)
java.lang.NoSuchMethodError: 'void com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.writeToServer(com.microsoft.sqlserver.jdbc.ISQLServerBulkData)'
        at com.microsoft.sqlserver.jdbc.spark.BulkCopyUtils$.bulkWrite(BulkCopyUtils.scala:110)
        at com.microsoft.sqlserver.jdbc.spark.BulkCopyUtils$.savePartition(BulkCopyUtils.scala:58)
        at com.microsoft.sqlserver.jdbc.spark.SingleInstanceWriteStrategies$.$anonfun$write$2(BestEffortSingleInstanceStrategy.scala:43)
        at com.microsoft.sqlserver.jdbc.spark.SingleInstanceWriteStrategies$.$anonfun$write$2$adapted(BestEffortSingleInstanceStrategy.scala:42)
        at org.apache.spark.rdd.RDD.$anonfun$foreachPartition$2(RDD.scala:1020)
        at org.apache.spark.rdd.RDD.$anonfun$foreachPartition$2$adapted(RDD.scala:1020)
        at org.apache.spark.SparkContext.$anonfun$runJob$5(SparkContext.scala:2236)
        at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:90)
        at org.apache.spark.scheduler.Task.run(Task.scala:131)
        at org.apache.spark.executor.Executor$TaskRunner.$anonfun$run$3(Executor.scala:497)
        at org.apache.spark.util.Utils$.tryWithSafeFinally(Utils.scala:1439)
        at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:500)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:829)

数据写入代码

try:
    (
        df.write.format("com.microsoft.sqlserver.jdbc.spark")
            .mode("append")
            .option("url", url)
            .option("dbtable", table_name)
            .option("user", username)
            .option("password", password)
            .option("schemaCheckEnabled", "false")
            .save()
    )
except ValueError as error:
    print("Connector write failed", error)

已尝试操作

  • 更换多个Spark版本、SQL连接器版本,问题未解决
  • 直接指定本地mssql-jdbc依赖jar包路径:
SparkSession.builder
   .config('spark.jars', '/mssql-jdbc-8.4.1.jre8.jar')
   .config(...)

仍提示找不到对应方法,检查JDBC jar包源码可确认该方法已定义。


排查方案

该NoSuchMethodError为典型的类版本冲突问题,与业务代码逻辑无关,按以下优先级排查:

  • 修复类加载顺序冲突
    核心原因是Spark运行环境(集群节点预装jar、Spark默认jars目录、其他依赖传递引入)存在旧版本mssql-jdbc,类加载器默认优先加载旧版本jar,旧版本无writeToServer(ISQLServerBulkData)方法,即使通过spark.jars指定正确版本也不会被优先加载。
    处理操作:
    • 新增两项Spark配置:spark.driver.userClassPathFirst = true、spark.executor.userClassPathFirst = true,强制JVM优先加载用户指定的jar包,覆盖Spark自带依赖的加载优先级
    • 逐台检查所有Spark节点的$SPARK_HOME/jars目录、Hadoop公共lib目录,删除所有版本不匹配的mssql-jdbc相关jar,避免隐式引入冲突
  • 严格匹配官方兼容版本
    com.microsoft.azure:spark-mssql-connector_2.12:1.2.0官方编译时绑定的mssql-jdbc版本为8.2.2.jre8,随意升级JDBC版本到8.4.1会出现跨小版本方法签名不兼容问题,直接导致连接器调用失败。将依赖中的mssql-jdbc版本替换为官方绑定的8.2.2.jre8即可:
    SparkSession.builder
        .config('spark.jars.packages', 'org.apache.hadoop:hadoop-azure:3.2.0,org.apache.spark:spark-avro_2.12:3.1.2,com.microsoft.sqlserver:mssql-jdbc:8.2.2.jre8,com.microsoft.azure:spark-mssql-connector_2.12:1.2.0')
    
  • 排查传递依赖冲突
    如果项目引入过其他第三方包,可能通过依赖传递引入不兼容版本的mssql-jdbc,提交任务时通过verbose参数打印依赖树排查:
    spark-submit --verbose [任务其他提交参数] 2>&1 | grep mssql-jdbc
    
    定位到引入错误版本的依赖后,通过exclude规则排除对应冲突依赖即可。
  • 验证Jar实际加载版本
    在执行写入逻辑前增加调试代码,打印运行时实际加载的SQLServerBulkCopy类的来源jar路径,确认加载的是指定版本:
    import com.microsoft.sqlserver.jdbc.SQLServerBulkCopy
    print(SQLServerBulkCopy.getProtectionDomain().getCodeSource().getLocation())
    
    若打印出的jar路径不是指定的8.2.2版本,说明仍存在类加载优先级问题未处理干净。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 04:27:23