在 Pig Latin 中加载 UDF 时发生 ClassCastException 错误

Posted

技术标签:

【中文标题】在 Pig Latin 中加载 UDF 时发生 ClassCastException 错误【英文标题】:ClassCastException error while loading an UDF in Pig Latin 【发布时间】:2014-02-12 12:15:14 【问题描述】:

我是 Pig latin 的新手,正在尝试实现 UDF 但出现以下错误。

错误

[main] ERROR org.apache.pig.tools.grunt.Grunt - ERROR 1200: Pig script failed to parse: 
<line 5, column 28> Failed to generate logical plan. Nested exception: java.lang.ClassCastException: power cannot be cast to org.apache.pig.EvalFunc
Details at logfile: /home/training/pig_1392253062989.log

脚本

REGISTER 'hdfs://cloudera-vm:8020/user/training/pig/pow.jar';

base = load 'hdfs://cloudera-vm:8020/user/training/pig/base' using PigStorage(',') as (id:int,base:int);

exponent = load 'hdfs://cloudera-vm:8020/user/training/pig/exponents' using 
PigStorage(',') as (id:int,exp:int);

tab = join base by id, exponent by id;

tab2 = foreach tab generate $1 as base, $3 as exp;

fin = foreach tab2 generate power(tab2.$0,tab2.$1);

UDF

import java.io.IOException;

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


public class power extends EvalFunc<Integer>


    public Integer exec(Tuple arg0) throws IOException 
        int base = (Integer)arg0.get(0);
        int exponent = (Integer)arg0.get(1);
        int result=1;

        for(int i=1;i<=exponent;i++)
            result=result*base;

        return result;
    


数据文件

Base

1,2    
2,3
3,4    
4,5
5,6
6,7
7,8
8,9
9,10

exponents

1,2
2,3
3,3
4,4
5,2
6,5
7,7
8,4
9,5

【问题讨论】:

使用 jar 名称为您的 UDF 调用添加前缀。 pow.power(tab2.$0,tab2.$1) 仍然无法正常工作 fin = foreach tab2 generate pow.power(tab2.$0,tab2.$1); 2014-02-12 21:23:57,634 [main] 错误 org.apache.pig.tools.grunt.Grunt - 错误 1070:无法使用导入解析 pow.power:[,org.apache.pig.builtin.,org .apache.pig.impl.builtin.] 日志文件中的详细信息:/home/training/pig_1392258175870.log 你检查过 /home/training/pig_1392258175870.log 吗? 日志文件以“未能生成逻辑计划。嵌套异常:java.lang.RuntimeException:无法实例化:pow.power”开始 现在我注意到您的 UDF JAR 在 HDFS 上。我很确定它应该在本地文件系统上,而不是在 HDFS 上。 【参考方案1】:

如果您的目标是计算tab2.$0 ^ tab2.$1,您可能需要考虑使用内置的POW。否则,如果您真的想使用自己的 UDF,我建议将类放入包中,在您的 PIG 脚本中使用完全限定名称,并检查您的类路径。您的类路径中的某处可能有错误的类 pow

【讨论】:

我这样做并将我的 UDF 放入一个包中。运行时它没有显示任何错误,但是当我“转储”我的最终输出时,它显示“超出范围”错误,但说明命令正在运行。【参考方案2】:

好的,问题出在我的脚本命令中,因为我没有传递两个输入,导致“访问第二个字段时越界访问”的错误

注册'hdfs://0.0.0.0:8020/user/training/pig/pow.jar';

base = load 'hdfs://0.0.0.0:8020/user/training/pig/base' using PigStorage(',') as (id:int,base:int);

exponent = load 'hdfs://0.0.0.0:8020/user/training/pig/exponents' using PigStorage(',') as (id:int,exp:int);

tab = 通过 id 连接基数,通过 id 连接指数;

tab2 = foreach 选项卡生成 $1 作为基础,$3 作为 exp;

fin = foreach tab2 generate abc.power(base,exp) as res;

转储鳍;

最终的 Java 代码

enter code here

package abc;

import java.io.IOException;

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


public class power extends EvalFunc<Tuple> 

    public Tuple exec(Tuple input) throws IOException 

        int base = (Integer)input.get(0);
        int exponent = (Integer)input.get(1);
        double result=1.0;
        Tuple out = TupleFactory.getInstance().newTuple(3);

        for(int i=1;i<=exponent;i++)
                result=result*base;
        out.set(0, input.get(0));
        out.set(1, input.get(1));
        out.set(2, result);

        return out;

    


【讨论】:

以上是关于在 Pig Latin 中加载 UDF 时发生 ClassCastException 错误的主要内容,如果未能解决你的问题,请参考以下文章

仅使用 Pig Latin 在 Pig 中加载具有不同分隔符的非结构化数据

Pig UDF 或 Pig Latin 还是两者兼而有之?

在 PIG 中加载 CSV 文件

向 udf pig latin 发送矩阵

如何在 Pig Latin 中每行加载一个带有 JSON 数组的文件

在 PIG 中加载文件时如何忽略“(双引号)?