【问题标题】:Apache pig script, Error 1070: Java UDF could not resolve importApache pig 脚本,错误 1070:Java UDF 无法解析导入
【发布时间】:2015-09-23 23:40:33
【问题描述】:

我正在尝试编写一个 Java UDF,其最终目标是扩展/覆盖 PigStorage 的加载方法以支持多行条目。

我的猪脚本如下:

REGISTER udf.jar;
register 'userdef.py' using jython as parser;
A = LOAD 'test_data' USING PigStorage() AS row:chararray;
C = FOREACH A GENERATE myTOKENIZE.test();
DUMP D;

udf.jar 看起来像:

udf/myTOKENIZE.class

myTOKENIZE.java 导入 o​​rg.apache.pig.* 并且扩展了 EvalFunc。测试方法只返回一个 Hello world 字符串。

我遇到的问题是,当我尝试调用 myTOKENIZE 类的方法 test() 时出现错误 1070:错误 1070:无法使用导入解析 myTOKENIZE.test:[, java.lang., org. apache.pig.builtin., org.apache.pig.impl.builtin.] 想法?

【问题讨论】:

  • 正如您已经发现的那样,在这种情况下,您需要使用完整的包名 udf.myTOKENIZE.test() 调用 UDF。另一种方法是首先使用定义语句,例如define myTOKENIZE udf.myTOKENIZE(); 然后您可以通过 myTOKENIZE.test() 简单地使用 UDF

标签: java hadoop apache-pig user-defined-functions


【解决方案1】:

那么 myTOKENIZE 在 udf 包中吗?在这种情况下,您需要

C = FOREACH A GENERATE udf.myTOKENIZE.test();

【讨论】:

  • 我尝试这样做时仍然遇到同样的错误。我不知道我做错了什么。
【解决方案2】:

当你的 UDF 扩展 EvalFunc 时,我应该在 myTOKENIZE 类中有一个名为 exec() 的方法。

您的猪代码将如下所示:

C = FOREACH A GENERATE udf.myTOKENIZE(*);

请阅读http://pig.apache.org/docs/r0.7.0/udf.html#How+to+Write+a+Simple+Eval+Function

希望对您有所帮助。

【讨论】:

  • 弗雷德,谢谢您的回复!我已按照该教程进行操作,但是在尝试您的方法时仍然遇到相同的错误。 <file javaTest.pig, line 6, column 23> Failed to generate logical plan. Nested exception: org.apache.pig.backend.executionengine.ExecException: ERROR 1070: Could not resolve myTOKENIZE using imports: [, java.lang., org.apache.pig.builtin., org.apache.pig.impl.builtin.] 当我尝试按照教程并调用 myudfs.myTOKENIZE(*) 我得到 ERROR 2998: Unhandled internal error. myudfs/myTOKENIZE (wrong name: myudf/myTOKENIZE)
  • 实际上,您再次查看教程的建议确实提供了一些见解。调用 myudfs.myTOKENIZE(*); 的原因不起作用是因为我在 myTOKENIZE.java 中将包定义为 package myudf 而不是 package myudfs。我怀疑这是所有错误的根源。
【解决方案3】:

经过太多时间(和咖啡)和一堆反复试验后,我发现了我的问题。

重要提示:对于某些jar myudfs.jar,其中包含的类必须有包定义为myudfs。

修正后的代码如下:

REGISTER myudfs.jar;
register 'userdef.py' using jython as parser;
A = LOAD 'test_data' USING PigStorage() AS row:chararray;
C = FOREACH A GENERATE myudfs.myTOKENIZE('');
DUMP C;

myTOKENIZE.java:

package myudfs;
import java.io.IOException;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.Tuple;
import org.apache.pig.impl.util.WrappedIOException;
public class myTOKENIZE extends EvalFunc (String)
{
    public String exec(Tuple input) throws IOException {
        if (input == null || input.size() == 0)
            return null;
        try{
            String str = (String)input.get(0);
            return str.toUpperCase();
        }catch(Exception e){
            throw WrappedIOException.wrap("Caught exception processing input row ", e);
        }
    }
}

myudfs.jar的结构:

myudfs/myTOKENIZE.class

希望这对有类似问题的其他人有用!

【讨论】:

  • 我从来没有将包命名为与我的 jar 相同的东西,而且我使用 UDF 没有问题。我认为您找到了不正确的根本原因。你的课程最初放在哪个包中?
【解决方案4】:

这已经很晚了,但我认为解决方案是在您的猪中使用 udf 时,您必须使用您的包名称提供类的完全限定路径。 package com.evalfunc.udf;和权力是我的班级名称 public class Power extends EvalFunc<Integer> {....}

然后在 pig 中使用它时,首先在 pig 中注册 jar 文件,然后使用带有完整包名的 udf,例如:

record = LOAD '/user/fsbappdev/maitytest/pig/pigudf/power_data' USING PigStorage(',');

pow_result = foreach record generate com.evalfunc.udf.Power(base,exponent);

【讨论】:

    猜你喜欢
    • 2012-11-18
    • 1970-01-01
    • 2016-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多