spark查询报错org.apache.hadoop.hive.ql.exec.Utilities.copyTableJobPropertiesToConf方法不存在NoSuchMethodError

报错详情:

Exception in thread "main" java.lang.NoSuchMethodError: org.apache.hadoop.hive.ql.exec.Utilities.copyTableJobPropertiesToConf(Lorg/apache/hadoop/hive/ql/plan/TableDesc;Lorg/apache/hadoop/conf/Configuration;)V
	at org.apache.spark.sql.hive.HadoopTableReader$.initializeLocalJobConfFunc(TableReader.scala:349)
	at org.apache.spark.sql.hive.HadoopTableReader$$anonfun$12.apply(TableReader.scala:300)
	at org.apache.spark.sql.hive.HadoopTableReader$$anonfun$12.apply(TableReader.scala:300)
	at org.apache.spark.rdd.HadoopRDD$$anonfun$getJobConf$5$$anonfun$apply$3.apply(HadoopRDD.scala:180)
	at org.apache.spark.rdd.HadoopRDD$$anonfun$getJobConf$5$$anonfun$apply$3.apply(HadoopRDD.scala:180)
	at scala.Option.foreach(Option.scala:257)
	at org.apache.spark.rdd.HadoopRDD$$anonfun$getJobConf$5.apply(HadoopRDD.scala:180)
	at org.apache.spark.rdd.HadoopRDD$$anonfun$getJobConf$5.apply(HadoopRDD.scala:177)
	at scala.Option.getOrElse(Option.scala:121)
	at org.apache.spark.rdd.HadoopRDD.getJobConf(HadoopRDD.scala:171)
	at org.apache.spark.rdd.HadoopRDD.getPartitions(HadoopRDD.scala:200)
	at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:253)
	at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:251)
	at scala.Option.getOrElse(Option.scala:121)
	at org.apache.spark.rdd.RDD.partitions(RDD.scala:251)
	at org.apache.spark.rdd.MapPartitionsRDD.getPartitions(MapPartitionsRDD.scala:49)
	at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:253)
	at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:251)
	at scala.Option.getOrElse(Option.scala:121)
	at org.apache.spark.rdd.RDD.partitions(RDD.scala:251)
	at org.apache.spark.rdd.MapPartitionsRDD.getPartitions(MapPartitionsRDD.scala:49)
	at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:253)

产生原因:spark与hive版本不匹配

分析过程:

根据报错堆栈找到对应代码:

 def initializeLocalJobConfFunc(path: String, tableDesc: TableDesc)(jobConf: JobConf) {
    FileInputFormat.setInputPaths(jobConf, Seq[Path](new Path(path)): _*)
    if (tableDesc != null) {
      HiveTableUtil.configureJobPropertiesForStorageHandler(tableDesc, jobConf, true)
      Utilities.copyTableJobPropertiesToConf(tableDesc, jobConf)
    }
    val bufferSize = System.getProperty("spark.buffer.size", "65536")
    jobConf.set("io.file.buffer.size", bufferSize)
  }
  public static void copyTableJobPropertiesToConf(TableDesc tbl, JobConf job) throws HiveException {
        Properties tblProperties = tbl.getProperties();
        Iterator var3 = tblProperties.stringPropertyNames().iterator();

        while(var3.hasNext()) {
            String name = (String)var3.next();
            if (job.get(name) == null) {
                String val = (String)tblProperties.get(name);
                if (val != null) {
                    job.set(name, StringEscapeUtils.escapeJava(val));
                }
            }
        }

        Map<String, String> jobProperties = tbl.getJobProperties();
        if (jobProperties != null) {
            Iterator var9 = jobProperties.entrySet().iterator();

            while(var9.hasNext()) {
                Entry<String, String> entry = (Entry)var9.next();
                job.set((String)entry.getKey(), (String)entry.getValue());
            }
        }

        try {
            Map<String, String> jobSecrets = tbl.getJobSecrets();
            if (jobSecrets != null) {
                Iterator var12 = jobSecrets.entrySet().iterator();

                while(var12.hasNext()) {
                    Entry<String, String> entry = (Entry)var12.next();
                    job.getCredentials().addSecretKey(new Text((String)entry.getKey()), ((String)entry.getValue()).getBytes());
                    UserGroupInformation.getCurrentUser().getCredentials().addSecretKey(new Text((String)entry.getKey()), ((String)entry.getValue()).getBytes());
                }
            }

        } catch (IOException var7) {
            throw new HiveException(var7);
        }
    }
报错信息显示第二个方法入参是Configuration类型,从源码中可以看出第二个方法入参明明是JobConf,怎么变成Configuration了。JobConf是Configuration子类,这里已经很明显入参类型被转换成父类,导致方法签名不一致抛出异常,但源码中是没有转换,传入的是JobConf类型,问题是出在编译后的代码自动转为父类了,反编译class文件查看

产生原因是该spark jar包与低版本hive一起编译,导致编译的class文件入参类型JobConf转为父类了,查看低版本hive方法如下:

  public static void copyTableJobPropertiesToConf(TableDesc tbl, Configuration job) {
    Properties tblProperties = tbl.getProperties();
    for(String name: tblProperties.stringPropertyNames()) {
      if (job.get(name) == null) {
        String val = (String) tblProperties.get(name);
        if (val != null) {
          job.set(name, StringEscapeUtils.escapeJava(val));
        }
      }
    }
    Map<String, String> jobProperties = tbl.getJobProperties();
    if (jobProperties == null) {
      return;
    }
    for (Map.Entry<String, String> entry : jobProperties.entrySet()) {
      job.set(entry.getKey(), entry.getValue());
    }
  }

### 关于 Hive MapRedTask 执行时返回错误代码 2 的解决方案 当遇到 `Execution Error, return code 2` 错误时,通常意味着在执行过程中遇到了更严重的失败情况。这类问题可能由多种原因引起,包括但限于资源足、配置当或数据倾斜等问题。 #### 调查日志文件 为了更好地理解具体的原因,建议先查看 HadoopHive 日志文件中的详细信息。这些日志可以提供有关作业执行期间发生的任何异常的具体线索[^1]。 #### 增加动态分区设置 如果问题是由于过多的动态分区引起的,则可以通过调整相关参数来解决此问题: ```sql SET hive.exec.dynamic.partition=true; SET hive.exec.max.dynamic.partitions=4096; SET hive.exec.max.dynamic.partitions.pernode=512; ``` 通过上述命令增加最大允许创建的动态分裂数量可能会缓解因过度分割而导致的任务失败问题[^3]。 #### 验证依赖库版本兼容性 有时,同组件之间的版本匹配也会引发此类错误。确保所使用的 Hive JDBC 及服务端 JAR 文件与集群环境相适应非常重要。例如,在 CDH 平台上操作 Spark Shell 连接 Hive 时曾出现过类似的连接建立失败的情况,其根本原因是缺少必要的客户端协议字段设定。此时应确认已上传正确的驱动程序包至指定路径并重启相应服务[^2]。 #### 检查资源配置 对于 Tez 或 MR 模式的任务来说,合理的内存分配和其他硬件资源管理同样可忽视。适当调优 YARN 容器大小及其他性能参数有助于提高整体稳定性。 #### 数据预处理优化 最后还需注意输入数据集的质量控制。存在大量空值或是极端分布的数据特征都可能导致计算过程稳定甚至崩溃。因此提前做好清洗工作也是预防该类故障的有效手段之一。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值