在Hive中开发UDTF时获取ClassCastException

时间:2013-10-07 16:24:42

标签: java hadoop hive

我在Hive中开发UDTF时遇到问题ClassCastException。

以下是详细信息:

  1. 我正在尝试实现循环类功能,我可以传递三个参数,如for_each(start,stop,increment)。
  2. 如果我将所有参数作为像for_each(1,10,1)这样的值传递它可以正常工作。
  3. 然而,对于stop值参数,我试图传递一个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”
  4. 这是我的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
    
        }
    }
    

    任何想法如何解决此问题?

    提前致谢

1 个答案:

答案 0 :(得分:0)

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

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