无法在配置单元中添加 UDF

Posted

技术标签:

【中文标题】无法在配置单元中添加 UDF【英文标题】:Unable to add UDF in hive 【发布时间】:2016-07-23 10:19:15 【问题描述】:

我必须在 hive 中添加以下 UDF:

package com.hadoopbook.hive;

import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;

public class Strip extends UDF 
  private Text result = new Text();

  public Text evaluate(Text str) 
    if (str == null) 
      return null;
    
    result.set(StringUtils.strip(str.toString()));
    return result;
  

  public Text evaluate(Text str, String stripChars) 
    if (str == null) 
      return null;
    
    result.set(StringUtils.strip(str.toString(), stripChars));
    return result;
  

这是《Hadoop:权威指南》一书中的一个例子

    我使用以下命令创建了上述java文件的.class文件:

    hduser@nb-VPCEH35EN:~/Hadoop-tutorial/hadoop-book-master/ch17-hive/src/main/java/com/hadoopbook/hive$ javac Strip.java 
    

    然后我使用以下命令创建了 jar 文件:

    hduser@nb-VPCEH35EN:~/Hadoop-tutorial/hadoop-book-master/ch17-hive/src/main/java/com/hadoopbook/hive$ jar cvf Strip.jar Strip Strip.class 
    Strip : no such file or directory
    added manifest
    adding: Strip.class(in = 915) (out= 457)(deflated 50%)
    

    我将生成的 jar 文件添加到 hdfs 目录:

    hduser@nb-VPCEH35EN:~/Hadoop-tutorial/hadoop-book-master/ch17-hive/src/main/java/com/hadoopbook/hive$ hadoop dfs -copyFromLocal /home/hduser/Hadoop-tutorial/hadoop-book-master/ch17-hive/src/main/java/com/hadoopbook/hive/Strip.jar /user/hduser/input
    

    我尝试使用以下命令创建 UDf:

    hive> create function strip as 'com.hadoopbook.hive.Strip' using jar 'hdfs://localhost/user/hduser/input/Strip.jar';
    

但我收到如下错误:

转换为本地 hdfs://localhost/user/hduser/input/Strip.jar 添加 [/tmp/hduser_resources/Strip.jar] 到类路径添加资源: [hdfs://localhost/user/hduser/input/Strip.jar] 注册失败 default.strip 使用类 com.hadoopbook.hive.Strip 失败:执行 错误,从 org.apache.hadoop.hive.ql.exec.FunctionTask 返回代码 1

    我也尝试创建临时函数。 所以我首先将 jar 文件添加到配置单元中:

    hive> add jar hdfs://localhost/user/hduser/input/Strip.jar;
    converting to local hdfs://localhost/user/hduser/input/Strip.jar
    Added [/tmp/hduser_resources/Strip.jar] to class path
    Added resources: [hdfs://localhost/user/hduser/input/Strip.jar]
    

    然后我尝试添加临时功能:

    hive> create temporary function strip as 'com.hadoopbook.hive.Strip';
    

但我收到以下错误:

失败:找不到类 com.hadoopbook.hive.Strip 失败:执行 错误,从 org.apache.hadoop.hive.ql.exec.FunctionTask 返回代码 1

jar 文件已成功创建并添加到 hive。仍然显示找不到该类。 谁能告诉它有什么问题?

【问题讨论】:

为什么你的 jar 命令有Stripjar cvf Strip.jar Strip Strip.class。您可以尝试将您的 jar 构建为 jar cvf Strip.jar Strip.class 并重新运行吗?我使用你的 Eclipse 程序构建了 jar,它运行良好。 Thanks.Creating jar from eclipse 工作。但是使用 jar cvf Strip.jar Strip.class 命令构建仍然无法正常工作。这很奇怪。 是的 - 请参阅下面关于如何正确使用命令行创建 jar 的答案。 - 如果您的疑虑很清楚,请接受此作为答案(在下方标上正确的绿色符号)。 【参考方案1】:

是的,使用 Eclipse 之类的 IDE 很容易,然后从 CLI 制作 jar。

从命令行创建 jar 文件您必须按照以下步骤操作:

首先在项目目录ch17-hive下制作项目目录:

bin - 将存储 .class (Strip.class) 文件 lib - 将存储所需的外部 jars

traget - 将存储您将创建的罐子

[ch17-hive]$ mkdir bin lib traget
[ch17-hive]$ ls
bin  lib  src  target

将所需的外部 jar 复制到 ch170hive/lib 目录:

[ch17-hive]$ cp /usr/lib/hive/lib/hive-exec.jar lib/.
[ch17-hive]$ cp /usr/lib/hadoop/hadoop-common.jar lib/.

现在从您的类 com.hadoopbook.hive.Strip 所在的目录编译 java,在您的情况下为 ch17-hive/src/main/java

[java]$ pwd
/home/cloudera/ch17-hive/src/main/java
[java]$ javac  -d ../../../bin -classpath ../../../lib/hive-exec.jar:../../../lib/hadoop-common.jar com/hadoopbook/hive/Strip.java 

创建清单文件为:

[ch17-hive]$ cat MENIFEST.MF 
Main-Class: com.hadoopbook.hive.Strip
Class-Path: lib/hadoop-common.jar  lib/hive-exec.jar

创建 jar 为

[ch17-hive]$ jar cvfm target/strip.jar MENIFEST.MF -C bin .added manifest
adding: com/(in = 0) (out= 0)(stored 0%)
adding: com/hadoopbook/(in = 0) (out= 0)(stored 0%)
adding: com/hadoopbook/hive/(in = 0) (out= 0)(stored 0%)
adding: com/hadoopbook/hive/Strip.class(in = 915) (out= 456)(deflated 50%)

现在您的项目结构应如下所示:

[ch17-hive]$ ls *
MENIFEST.MF

bin:
com

lib:
hadoop-common.jar  hive-exec.jar

src:
main

target:
strip.jar

将创建的 jar 复制到 hdfs:

hadoop fs -put /home/cloudera/ch17-hive/target/strip.jar /user/cloudera/.

在 HIVE 中使用它:

hive> create function strip_new as 'com.hadoopbook.hive.Strip' using jar 'hdfs:/user/cloudera/strip.jar';
converting to local hdfs:/user/cloudera/strip.jar
Added [/tmp/05a13d23-8051-431f-a354-793abac66160_resources/strip.jar] to class path
Added resources: [hdfs:/user/cloudera/strip.jar]
OK
Time taken: 0.071 seconds
hive>

【讨论】:

以上是关于无法在配置单元中添加 UDF的主要内容,如果未能解决你的问题,请参考以下文章

运行 sql 时配置单元 UDF 如何运行?

带分隔符的数据上的配置单元 UDF

我们可以在 Spark 中编写配置单元查询吗?UDF

如何将配置从配置单元脚本传递到 UDF

更新配置单元 UDF 的 jar

如何为所有会话创建配置单元 UDF