我正在尝试为Hadoop Hive编写一个UDF,它解析用户代理。以下代码在我的本地机器上工作正常,但在Hadoop上我得到了:
org.apache.hadoop.hive.ql.metadata.HiveException:无法执行方法public java.lang.String MyUDF .evaluate(java.lang.String)throws org.apache.hadoop.hive.ql.metadata。 MyODF类的对象MyUDF @ 64ca8bfb上的HiveException,参数{All Occupations:java.lang.String},大小为1',
代码:
import java.io.IOException;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.*;
import com.decibel.uasparser.OnlineUpdater;
import com.decibel.uasparser.UASparser;
import com.decibel.uasparser.UserAgentInfo;
public class MyUDF extends UDF {
public String evaluate(String i) {
UASparser parser = null;
parser = new UASparser();
String key = "";
OnlineUpdater update = new OnlineUpdater(parser, key);
UserAgentInfo info = null;
info = parser.parse(i);
return info.getDeviceType();
}
}
我想到的事实应该提到:
我正在使用Eclipse编译“export runnable jar file”并将所需的库提取到生成的jar选项中
我正在使用Hue上传这个“胖罐”文件
我设法运行的最低工作示例:
public String evaluate(String i) {
return "hello" + i.toString()";
}
我想这个问题就在我正在使用的那个库(从https://udger.com下载)的某处,但我不知道在哪里。
有什么建议吗?
谢谢,Michal
答案 0 :(得分:1)
这可能是一些事情。最好的办法是检查日志,但这里列出了一些你可以在一分钟内查看的快速内容。
jar不包含所有依赖项。我不确定eclipse如何构建一个可运行的jar,但它可能不包含所有依赖项。你可以做到
jar tf your-udf-jar.jar
查看包含的内容。你应该看到来自com.decibel.uasparser
的东西。如果没有,您必须使用适当的依赖项构建jar(通常使用maven来实现)。
不同版本的JVM。如果使用jdk8进行编译并且集群运行jdk7,它也将失败
Hive版本。有时,Hive API会略有变化,足以使其不兼容。可能不是这里的情况,但请确保针对您在群集中具有的相同版本的hadoop和hive编译UDF
在致电info
parse()
是否为空
看起来图书馆使用密钥,这意味着实际上从在线服务(udger.com)获取数据,因此如果没有实际密钥,它可能无法运行。更重要的是,图书馆在线更新,联系每条记录的在线服务 。这意味着,查看代码,它将为每条记录创建一个更新线程。您应该更改代码,只在构造函数中执行一次,如下所示:
以下是如何更改它:
public class MyUDF extends UDF {
UASparser parser = new UASparser();
public MyUDF() {
super()
String key = "PUT YOUR KEY HERE";
// update only once, when the UDF is instantiated
OnlineUpdater update = new OnlineUpdater(parser, key);
}
public String evaluate(String i) {
UserAgentInfo info = parser.parse(i);
if(info!=null) return info.getDeviceType();
// you want it to return null if it's unparseable
// otherwise one bad record will stop your processing
// with an exception
else return null;
}
}
但是要确定,您必须查看日志...纱线日志,还可以查看您正在提交作业的计算机上的配置单元日志(可能在/ var / log / hive中)但这取决于你的安装。)
答案 1 :(得分:0)
这样的问题可能可以通过以下步骤解决:
覆盖方法UDF.getRequiredJars()
,使其返回hdfs
文件路径列表,其中的值由您将以下xxx_lib文件夹放入hdfs的位置确定。请注意,列表雾完全包含每个jar的完整hdfs路径字符串,例如hdfs://yourcluster/some_path/xxx_lib/some.jar
按照" Runnable jar文件导出向导"导出udf
代码。 (选择"将所需的库复制到生成的jar旁边的子文件夹中#34;。这些步骤将导致xxx.jar和xxx.jar旁边的lib文件夹xxx_lib
根据您在步骤0中的代码将xxx.jar和文件夹xxx_lib放入您的hdfs文件系统。
使用以下方法创建一个udf:add jar $ {the-xxx.jar-hdfs-path};创建函数your-function为$} udf class的限定名称};
试试吧。我测试了它并且它可以工作