spark - org.apache.hadoop.security.authentication.util.KerberosUtil.hasKerberosTicket报错解决小记

笔者遇到这个问题是在同事加入项目后,修改了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.<init>(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.<init>(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而在项目中引入的HadoopHadoop2.8.5 与使用的spark版本并不兼容。这样就有两个两种解决方案。

  • 一是使用默认版本的Hadoop版本。
  • 二就要分析当前的应用场景:
    当使用UDAF时,最终得到的jar将包含所有依赖项,包括通过直接依赖项引入的可传递依赖项。而项目中声明对Hadoop jar列表的依赖。如果要使用默认版本以外的其他版本的Hadoop,则需要确保在POM中声明了相同的Hadoop jar列表.
    由此我们进行对项目的pom文件进行排查,为了方便大家理解我们提供项目中使用到的POM如下:
<?xml version="1.0" encoding="UTF-8"?>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <encoding>UTF-8</encoding>
        <scala.version>2.12.8</scala.version>
        <spark.version>2.4.2</spark.version>
        <hadoop.version>2.8.5</hadoop.version>
        <hbase.version>1.4.13</hbase.version>
        <fastjson.version>1.2.47</fastjson.version>
        <log4j.version>1.2.17</log4j.version>
        <slf4j.version>1.7.12</slf4j.version>
        <mail.version>1.4.7</mail.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>${hadoop.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>${hadoop.version}</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>${hadoop.version}</version>
        </dependency>

    </dependencies>

最终原因定位:
由上面文件中我们发现了问题。具体情况是,尚未在POM中声明hadoop-auth,因此POM与该jar的默认版本(2.7)打包在一起.由于该版本的hadoop-auth与其他Hadoop jar(2.8.5)不兼容,因此在运行时会出现异常。
那么我们就应该从导入的依赖中排除所有Hadoop jar,然后将要使用的jar放入项目的lib目录中,或者将正确版本的Hadoop jar添加到`POM 中的依赖项列表中。
那么有人会疑惑了,这不是项目中已经有了hadoop相关的jar了吗?

         <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>${hadoop.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>${hadoop.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>${hadoop.version}</version>
        </dependency>

追到这里,我想我找到了问题.我们未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依赖对问题进行了解决。如下:

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <encoding>UTF-8</encoding>
        <scala.version>2.12.8</scala.version>
        <spark.version>2.4.2</spark.version>
        <hadoop.version>2.8.5</hadoop.version>
        <hbase.version>1.4.13</hbase.version>
        <fastjson.version>1.2.47</fastjson.version>
        <log4j.version>1.2.17</log4j.version>
        <slf4j.version>1.7.12</slf4j.version>
        <mail.version>1.4.7</mail.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>${hadoop.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>${hadoop.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-auth</artifactId>
            <version>${hadoop.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>${hadoop.version}</version>
        </dependency>
    </dependencies>
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

扫地增

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值