报错笔者遇到这个问题是在同事加入项目后,修改了pom.xml造成。直接上问题。
笔者是在写完了UDAF进行本地测试的时候遇到。
21/05/25 09:13:12 INFO SparkContext: Running Spark version 2.4.2 21/05/25 09:13:13 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable Exception in thread "main" java.lang.NoSuchMethodError: org.apache.hadoop.security.authentication.util.KerberosUtil.hasKerberosTicket(Ljavax/security/auth/Subject;)Z at org.apache.hadoop.security.UserGroupInformation.原因分析(UserGroupInformation.java:657) at org.apache.hadoop.security.UserGroupInformation.loginUserFromSubject(UserGroupInformation.java:848) at org.apache.hadoop.security.UserGroupInformation.getLoginUser(UserGroupInformation.java:807) at org.apache.hadoop.security.UserGroupInformation.getCurrentUser(UserGroupInformation.java:680) at org.apache.spark.util.Utils$.$anonfun$getCurrentUserName$1(Utils.scala:2422) at scala.Option.getOrElse(Option.scala:138) at org.apache.spark.util.Utils$.getCurrentUserName(Utils.scala:2422) at org.apache.spark.SparkContext. (SparkContext.scala:293) at org.apache.spark.SparkContext$.getOrCreate(SparkContext.scala:2520) at org.apache.spark.sql.SparkSession$Builder.$anonfun$getOrCreate$5(SparkSession.scala:935) at scala.Option.getOrElse(Option.scala:138) at org.apache.spark.sql.SparkSession$Builder.getOrCreate(SparkSession.scala:926) at GroupTest$.main(GroupTest.scala:22) at GroupTest.main(GroupTest.scala) Process finished with exit code 1
问题初步定位:
NoSuchMethod可能是因为项目中混合了多个版本的jar包,需要检查下项目依赖。由此我们进行了依赖的检查。我们查看依赖发现spark使用的是2.4.2版本,其默认的Hadoop版本是Hadoop 2.7而在项目中引入的Hadoop是Hadoop2.8.5 与使用的spark版本并不兼容。这样就有两个两种解决方案。
- 一是使用默认版本的Hadoop版本。
- 二就要分析当前的应用场景:
当使用UDAF时,最终得到的jar将包含所有依赖项,包括通过直接依赖项引入的可传递依赖项。而项目中声明对Hadoop jar列表的依赖。如果要使用默认版本以外的其他版本的Hadoop,则需要确保在POM中声明了相同的Hadoop jar列表.
由此我们进行对项目的pom文件进行排查,为了方便大家理解我们提供项目中使用到的POM如下:
UTF-8
1.8
1.8
UTF-8
2.12.8
2.4.2
2.8.5
1.4.13
1.2.47
1.2.17
1.7.12
1.4.7
org.apache.hadoop
hadoop-client
${hadoop.version}
org.apache.hadoop
hadoop-common
${hadoop.version}
org.apache.hadoop
hadoop-hdfs
${hadoop.version}
最终原因定位:
由上面文件中我们发现了问题。具体情况是,尚未在POM中声明hadoop-auth,因此POM与该jar的默认版本(2.7)打包在一起.由于该版本的hadoop-auth与其他Hadoop jar(2.8.5)不兼容,因此在运行时会出现异常。
那么我们就应该从导入的依赖中排除所有Hadoop jar,然后将要使用的jar放入项目的lib目录中,或者将正确版本的Hadoop jar添加到`POM 中的依赖项列表中。
那么有人会疑惑了,这不是项目中已经有了hadoop相关的jar了吗?
org.apache.hadoop hadoop-client ${hadoop.version} org.apache.hadoop hadoop-common ${hadoop.version} org.apache.hadoop hadoop-hdfs ${hadoop.version}
解决方案追到这里,我想我找到了问题.我们未spark-core的范围设置为提供。由于spark-core取决于hadoop-auth,并且我们未明确声明具体版本,因此Maven将尝试根据依赖关系在树中的位置来猜测所需的hadoop-auth版本。由于hadoop-auth在某些Hadoop依赖项中显示为2.8.5,而在spark-core中显示为2.7,因此您碰巧将2.7放入了jar。
考虑到集群中hadoop的版本,我们最终引入了hadoop-auth依赖对问题进行了解决。如下:
UTF-8 1.8 1.8 UTF-8 2.12.8 2.4.2 2.8.5 1.4.13 1.2.47 1.2.17 1.7.12 1.4.7 org.apache.hadoop hadoop-client ${hadoop.version} org.apache.hadoop hadoop-common ${hadoop.version} org.apache.hadoop hadoop-auth ${hadoop.version} org.apache.hadoop hadoop-hdfs ${hadoop.version}



