Pig的UDF中存在“in”会导致问题

时间:2015-06-02 17:04:16

标签: hadoop apache-pig udf

我在猪身上尝试了我的第一个UDF并编写了以下功能 -

package com.pig.in.action.assignments.udf;

import org.apache.pig.EvalFunc;
import org.apache.pig.PigWarning;
import org.apache.pig.data.Tuple;

import java.io.IOException;


public class CountLength extends EvalFunc<Integer> {

    public Integer exec(Tuple inputVal) throws IOException {

        // Validate Input Value ...
        if (inputVal == null ||
            inputVal.size() == 0 ||
            inputVal.get(0) == null) {

            // Emit warning text for user, and skip this iteration
            super.warn("Inappropriate parameter, Skipping ...",
                       PigWarning.SKIP_UDF_CALL_FOR_NULL);
            return null;
        }

        // Count # of characters in this string ...
        final String inputString = (String) inputVal.get(0);

        return inputString.length();

    }

}

但是,当我尝试按如下方式使用它时,Pig会抛出一条错误消息,在我的UDF环境中至少对我来说并不容易理解:

grunt> cat dept.txt;
10,ACCOUNTING,NEW YORK
20,RESEARCH,DALLAS
30,SALES,CHICAGO
40,OPERATIONS,BOSTON

grunt> dept = LOAD '/user/sgn/dept.txt' USING PigStorage(',') AS (dept_no: INT, d_name: CHARARRAY, d_loc: CHARARRAY);
grunt> d = FOREACH dept GENERATE dept_no, com.pig.in.action.assignments.udf.CountLength(d_name);

2015-06-02 16:24:13,416 [main] ERROR org.apache.pig.tools.grunt.Grunt - ERROR 1200: <line 2, column 79>  mismatched input '(' expecting SEMI_COLON
Details at logfile: /home/sgn/pig_1433261973141.log

任何人都可以帮我弄清楚这有什么不对吗?

我已经阅读了文档,但对我来说似乎没有什么是明显错误的。我在这里错过了什么吗?

这些是我在pom.xml中使用的库:

<dependency>
    <groupId>org.apache.pig</groupId>
    <artifactId>pig</artifactId>
    <version>0.14.0</version>
</dependency>

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-core</artifactId>
    <version>1.2.1</version>
</dependency>

是否存在兼容性问题?

谢谢,

-Vipul Pathak;

3 个答案:

答案 0 :(得分:3)

在停机约36小时后找到问题的原因......

包裹名称包含“ IN ”,这在某种程度上是Pig的问题。

package com.pig.in.action.assignments.udf;
//              ^^

当我将包名更改为以下内容时,一切都很好 -

package com.pig.nnn.action.assignments.udf;
//              ^^^

在构建我修改过的UDF之后,我注册了Jar并定义了函数名和宾果游戏的别名,一切正常 -

REGISTER /user/sgn/UDFs/Pig/CountLength-1.jar;
DEFINE  CL  com.pig.nnn.action.assignments.udf.CountLength;

.   .   .
.   .   .
d = FOREACH dept GENERATE dept_no, CL(d_name) AS DeptLength;

我不记得 IN 是否是Pig中的保留字。但仍然存在IN导致问题,(至少在猪的0.14.0版本中)。

答案 1 :(得分:2)

试过上面的例子。只要使用REGISTER命令注册jar并且jar在classpath中可用,我们就不应该看到任何错误。

REGISTER myudfs.jar;
dept = LOAD 'a.csv' USING PigStorage(',') AS (dept_no: INT, d_name: CHARARRAY, d_loc: CHARARRAY);
d = FOREACH dept GENERATE dept_no, CountLength(d_name) as length;

输入:a.csv

10,ACCOUNTING,NEW YORK
20,RESEARCH,DALLAS
30,SALES,CHICAGO
40,OPERATIONS,BOSTON

输出:d

(10,10)
(20,8)
(30,5)
(40,10)

<强> N.B。 :在上面的运行中,类CountLength已在默认包中定义。

如果在com.pig.utility包中定义了这个类 - CountLength然后访问UDF,我们必须有一个DEFINE语句,如下所示

DEFINE CountLength com.pig.utility.CountLength;

我们必须通过完整路径引用UDF,如下所示:

d = FOREACH dept GENERATE dept_no, com.pig.utility.CountLength(d_name) as length;

答案 2 :(得分:1)

你的罐子应该注册 例如:

REGISTER /home/hadoop/udf.jar;  

DEFINE package.CountLength CountLength ;