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

使用decline解析Spark应用命令行参数时遇cats依赖错误

Spark加载Decline胖Jar时出现java.lang.NoSuchMethodError: cats.kernel.Semigroup$.catsKernelMonoidForList()错误

问题场景

使用Decline库为Spark应用做命令行参数解析,通过sbt assembly构建胖Jar后,用spark-shell --jars加载该包并调用参数解析方法时,抛出如下错误:

java.lang.NoSuchMethodError: cats.kernel.Semigroup$.catsKernelMonoidForList()Lcats/kernel/Monoid;
  at com.monovore.decline.Help$.optionList(Help.scala:74)
  ...

但将该Jar添加到本地Scala环境类路径运行时,能正常返回预期的帮助信息;切换Scala 2.13+Spark 3.2.2组合,问题依然存在。

问题原因

这是依赖版本冲突导致的:

  • Decline 2.3.0依赖的是Cats 2.x版本(包含catsKernelMonoidForList方法)
  • Spark 3.1.2/3.2.2内置的是Cats 1.x旧版本(该方法不存在)

Spark启动时会优先加载自身内置的依赖类,导致运行时JVM找不到新版Cats才有的方法,抛出NoSuchMethodError。

解决方案

方案1:用sbt-assembly的Shade规则重命名Cats包

通过重命名Decline依赖的Cats类,避免和Spark内置的Cats冲突:

  1. 确保已添加sbt-assembly插件,在project/plugins.sbt中:
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "1.2.0")
  1. 修改build.sbt,添加Shade规则:
name := "example"
version := "0.1"

scalaVersion := "2.12.10"

libraryDependencies ++= Seq("com.monovore" %% "decline" % "2.3.0")

assemblyShadeRules in assembly := Seq(
  ShadeRule.rename("cats.**" -> "my.cats.@1")
    .inLibrary("org.typelevel" %% "cats-kernel" % "2.9.0")
    .inLibrary("org.typelevel" %% "cats-core" % "2.9.0")
    .inProject
)

重新执行sbt assembly构建后,Jar中的Cats类会被重命名到my.cats包下,运行时会优先加载这个重命名后的新版Cats类。

方案2:适配Spark的Cats版本选择Decline版本

Spark 3.x内置的是Cats 1.x,可改用依赖Cats 1.x的Decline 1.x版本,修改build.sbt:

libraryDependencies ++= Seq("com.monovore" %% "decline" % "1.4.0")

注意:Decline 1.x的API和2.x存在差异,需要微调代码适配(比如部分方法的导入或调用方式)。

方案3:强制Spark优先加载用户Jar(不推荐)

启动spark-shell时添加类加载顺序配置,强制优先加载用户Jar的依赖:

spark-shell --jars target/scala-2.12/example-assembly-0.1.jar \
  --conf spark.driver.userClassPathFirst=true \
  --conf spark.executor.userClassPathFirst=true

该方法可能破坏Spark自身依赖的兼容性,导致其他未知问题,谨慎使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 17:36:30