NoSuchMethodError: org.apache.hadoop.conf.Configuration.getPassword
NoSuchMethodError: org.apache.hadoop.conf.Configuration.getPassword
我已经在 Spark 项目中为这个 NoSuchMethodError
苦苦挣扎了一段时间,现在一无所获。目前,该项目 运行 在本地使用 SparkNLP 3.3.0 和 Spark-Core/SparkMLLib 3.1.2,两者均使用 Scala 2.12.4。 Hadoop 3.2.0 通过 spark-core 作为传递依赖引入。
到目前为止我尝试过的:
- 通过逐步执行代码检查此方法是否确实存在
- 验证所有依赖项的统一 Scala 版本
- 验证 spark 和 hadoop 版本是否始终相同(使用 maven dep tree 和 enforcer 插件)
- 从本地 .m2 目录中手动删除其他版本的 Hadoop
代码是 运行 来自可执行 JAR 的代码,该 JAR 将其他 jar 拉入运行时提供的类路径。 Java 版本为 1.8。0_282。 Maven 是 3.6.3 版本。 OS 是大苏尔,11.6 (M1)。
Exception in thread "main" java.lang.NoSuchMethodError: org.apache.hadoop.conf.Configuration.getPassword(Ljava/lang/String;)[C
at org.apache.spark.SSLOptions$.$anonfun$parse(SSLOptions.scala:188)
at scala.Option.orElse(Option.scala:289)
at org.apache.spark.SSLOptions$.parse(SSLOptions.scala:188)
at org.apache.spark.SecurityManager.<init>(SecurityManager.scala:98)
at org.apache.spark.SparkEnv$.create(SparkEnv.scala:252)
at org.apache.spark.SparkEnv$.createDriverEnv(SparkEnv.scala:189)
at org.apache.spark.SparkContext.createSparkEnv(SparkContext.scala:277)
at org.apache.spark.SparkContext.<init>(SparkContext.scala:458)
at org.apache.spark.SparkContext$.getOrCreate(SparkContext.scala:2672)
at org.apache.spark.sql.SparkSession$Builder.$anonfun$getOrCreate(SparkSession.scala:945)
at scala.Option.getOrElse(Option.scala:121)
at org.apache.spark.sql.SparkSession$Builder.getOrCreate(SparkSession.scala:939)
[...]
at com.mymainpackage.Main.main(Main.java:157)
我终于弄明白了。
根本原因是引入了旧版本的 hadoop-core(1.2.1 而不是 2.6.5),它实际上没有 Configuration.getPassword()
方法。我在设置一个正确初始化 SparkContext 的测试项目然后检查两个项目中的两个配置 类 的源 jar 后发现了这一点(使用 Configuration.class.getProtectionDomain().getCodeSource().getLocation().getPath()
)。
在使用 Maven 的依赖管理强制版本 2.6.5 并从本地 Maven 仓库中手动删除旧的 1.2.1 jar 后,它工作正常。
我唯一不明白的是为什么 hadoop-core
没有出现在 Maven 依赖树中。否则,我会早点找到(可能)。
我已经在 Spark 项目中为这个 NoSuchMethodError
苦苦挣扎了一段时间,现在一无所获。目前,该项目 运行 在本地使用 SparkNLP 3.3.0 和 Spark-Core/SparkMLLib 3.1.2,两者均使用 Scala 2.12.4。 Hadoop 3.2.0 通过 spark-core 作为传递依赖引入。
到目前为止我尝试过的:
- 通过逐步执行代码检查此方法是否确实存在
- 验证所有依赖项的统一 Scala 版本
- 验证 spark 和 hadoop 版本是否始终相同(使用 maven dep tree 和 enforcer 插件)
- 从本地 .m2 目录中手动删除其他版本的 Hadoop
代码是 运行 来自可执行 JAR 的代码,该 JAR 将其他 jar 拉入运行时提供的类路径。 Java 版本为 1.8。0_282。 Maven 是 3.6.3 版本。 OS 是大苏尔,11.6 (M1)。
Exception in thread "main" java.lang.NoSuchMethodError: org.apache.hadoop.conf.Configuration.getPassword(Ljava/lang/String;)[C
at org.apache.spark.SSLOptions$.$anonfun$parse(SSLOptions.scala:188)
at scala.Option.orElse(Option.scala:289)
at org.apache.spark.SSLOptions$.parse(SSLOptions.scala:188)
at org.apache.spark.SecurityManager.<init>(SecurityManager.scala:98)
at org.apache.spark.SparkEnv$.create(SparkEnv.scala:252)
at org.apache.spark.SparkEnv$.createDriverEnv(SparkEnv.scala:189)
at org.apache.spark.SparkContext.createSparkEnv(SparkContext.scala:277)
at org.apache.spark.SparkContext.<init>(SparkContext.scala:458)
at org.apache.spark.SparkContext$.getOrCreate(SparkContext.scala:2672)
at org.apache.spark.sql.SparkSession$Builder.$anonfun$getOrCreate(SparkSession.scala:945)
at scala.Option.getOrElse(Option.scala:121)
at org.apache.spark.sql.SparkSession$Builder.getOrCreate(SparkSession.scala:939)
[...]
at com.mymainpackage.Main.main(Main.java:157)
我终于弄明白了。
根本原因是引入了旧版本的 hadoop-core(1.2.1 而不是 2.6.5),它实际上没有 Configuration.getPassword()
方法。我在设置一个正确初始化 SparkContext 的测试项目然后检查两个项目中的两个配置 类 的源 jar 后发现了这一点(使用 Configuration.class.getProtectionDomain().getCodeSource().getLocation().getPath()
)。
在使用 Maven 的依赖管理强制版本 2.6.5 并从本地 Maven 仓库中手动删除旧的 1.2.1 jar 后,它工作正常。
我唯一不明白的是为什么 hadoop-core
没有出现在 Maven 依赖树中。否则,我会早点找到(可能)。