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

Posted 扫地增

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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>

以上是关于spark - org.apache.hadoop.security.authentication.util.KerberosUtil.hasKerberosTicket报错解决小记的主要内容,如果未能解决你的问题,请参考以下文章

idea运行spark项目报错:org.apache.hadoop.io.nativeio.NativeIO$Windows.createDirectoryWithMode0

原创问题定位分享(16)spark写数据到hive外部表报错ClassCastException: org.apache.hadoop.hive.hbase.HiveHBaseTableOutpu(代

从 spark(2.11) 数据帧写入 hive 分区表时出现 org.apache.hadoop.hive.ql.metadata.Hive.loadDynamicPartitions 异常

类 org.apache.hadoop.fs.s3native.NativeS3FileSystem 未找到(Spark 1.6 Windows)

找不到 Spark 和 Cassandra Java 应用程序异常提供程序 org.apache.hadoop.fs.s3.S3FileSystem

return code 3 from org.apache.hadoop.hive.ql.exec.spark.SparkTask.