0

在 Hive 中开发 UDTF 时出现 ClassCastException 问题。

以下是详细信息:

  1. 我正在尝试实现 for 循环类型的功能,我可以在其中传递三个参数,例如 for_each(start,stop,increment)。
  2. 如果我将所有参数作为值传递,例如 for_each(1 , 10 , 1) 它工作正常。
  3. 而对于停止值参数,我试图传递 UDF 函数之一的结果(例如,stopvlaue() 值,如 for_each(1,stopvalue(),1)。stopo dovalue() 函数返回 IntWritable。当我尝试这样做我得到以下异常:“ClassCastException org.apache.hadoop.hive.serde2.objectinspector.primitive.WritableIntObjectInspector 不能转换为 org.apache.hadoop.hive.serde2.objectinspector.primitive.WritableConstantIntObjectInspector”

这是我的 UDTF:

public class GenerateSeries extends GenericUDTF {
    IntWritable start;
    IntWritable end;
    IntWritable inc;
    Object[] forwardObj = null;



    @Override
    public StructObjectInspector initialize(ObjectInspector[] args) throws UDFArgumentException 
    {

        start=((WritableConstantIntObjectInspector) args[0]).getWritableConstantValue();
        end=((WritableConstantIntObjectInspector) args[1]).getWritableConstantValue();
        if (args.length == 3) 
        {
            inc =((WritableConstantIntObjectInspector) args[2]).getWritableConstantValue();
        } else {
            inc = new IntWritable(1);
        }
        this.forwardObj = new Object[1];
        ArrayList<String> fieldNames = new ArrayList<String>();
        ArrayList<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>();
        fieldNames.add("col0");
        fieldOIs.add(PrimitiveObjectInspectorFactory.getPrimitiveJavaObjectInspector(PrimitiveCategory.INT));
        return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs);
    }
    @Override
    public void process(Object[] args) throws HiveException, UDFArgumentException 
    {
        for (int i = start.get(); i < end.get(); i = i + inc.get()) 
        {
            this.forwardObj[0] = new Integer(i);
            forward(forwardObj);
        }
    }

    @Override
    public void close() throws HiveException {
        // TODO Auto-generated method stub

    }
}

任何想法我该如何解决这个问题?

提前致谢

4

1 回答 1

0

在大多数情况下,该initialize方法不会为您提供函数输入的实际值,因为不同的行可能会有所不同。它只告诉你输入的类型。实际值只能从该process方法一致地访问。您目前正在利用一个值得注意的例外,即常量。您应该遵循的一般模式是:

  1. 将输入检查器存储在initialize方法中的实例变量中。您可以检查它们是否是您期望的类型,但它们并不总是WritableConstantIntObjectInspector. 它们应该始终是的子类,PrimitiveObjectInspector如果您调用该getPrimitiveCategory方法,您应该返回PrimtiveCategory.INT.
  2. 使用存储的输入检查器检索传入process方法的对象中的数据。例如,Integer n = (Integer)inspector.getPrimitiveJavaObject(args[0])
于 2013-10-07T21:06:23.717 回答