Hive GenericUDF 返回数组<String> 错误

Posted

技术标签:

【中文标题】Hive GenericUDF 返回数组<String> 错误【英文标题】:Hive GenericUDF return array<String> Error 【发布时间】:2015-07-08 10:51:42 【问题描述】:

我是 GenericUDF 的新手。我正在尝试使用Array&lt;strings&gt; 生成一个创建电话号码的函数。

但我有一个错误:

原因:java.lang.ClassCastException: org.apache.hadoop.hive.serde2.lazy.LazyString 无法转换为 java.lang.String

在这一行:

字符串编号 = (String) listOi.getListElement(args[1].get(), i);

有人可以帮帮我吗?谢谢。

这是我的代码:

@Description(name = "create_numbers",
value = "_FUNCT_(prefix, array(number1, number2, ...)); first argument is a prefix(string) and the second argument is a array of strings."
        + "Return a list of phone numbers. "
        + "Example: prefix = +49 and arrayNumbers = Array[1234, 2346, 1356] - Result: Array[+491234, +492346, +491356].")

public class UDFGenericListNumbers extends GenericUDF 
ListObjectInspector     listOi;
StringObjectInspector   elemOi;

public Object evaluate(DeferredObject[] args) throws HiveException         

    // we must have 2 arguments
    if(args==null || args.length != 2) 
            throw new HiveException("received " + (args == null? "null" :
            Integer.toString(args.length) + " elements instead of 2"));
    

    String prefix = elemOi.getPrimitiveJavaObject(args[0].get());

    //if any of them null, return also null
    if(args[0] == null || args[1] == null)
        return null;
    

    List<String> resultlnumerbs = new ArrayList<String>();      
    int numElem = listOi.getListLength(args[1].get());

    for(int i=0; i<numElem; i++)           
        String inumber = (String) listOi.getListElement(args[1].get(), i);          
        resultlnumerbs.add(prefix + inumber);       
                 
    return resultlnumerbs;


public ObjectInspector initialize(ObjectInspector[] args) throws UDFArgumentException 

    // check number of arguments. We only accept two
    if (args.length != 2) 
          throw new UDFArgumentLengthException("Two arguments are needed: String and List<String>, found "+ args.length);
    

    //Check we received the right objects types.
    if (!(args[0] instanceof StringObjectInspector) || !(args[1] instanceof ListObjectInspector)) 
      throw new UDFArgumentException("first argument must be a string and the second argument must be a list / array of string");
    

    this.elemOi = (StringObjectInspector) args[0];
    this.listOi = (ListObjectInspector) args[1];

    //Check that the list contains strings
    if(!(listOi.getListElementObjectInspector() instanceof StringObjectInspector)) 
      throw new UDFArgumentException("second argument must be a list of strings");
    

    // the return type of our function is an array of string, so we provide the correct object inspector        
    return (StringObjectInspector)listOi.getListElementObjectInspector();


@Override
public String getDisplayString(String[] arg0) 
    return "create_numbers";



【问题讨论】:

【参考方案1】:

代替

String inumber = (String) listOi.getListElement(args[1].get(), i); 

试试

String inumber =  listOi.getListElement(args[1].get(), i).toString();

由于getListElement() 返回一个对象,所以它应该是可转换的。

【讨论】:

感谢您的回答,但错误仍然存​​在 原因:java.lang.ClassCastException:java.util.ArrayList 无法在 org.apache 上转换为 org.apache.hadoop.hive.serde2.lazy.LazyString .hadoop.hive.serde2.lazy.objectinspector.primitive.LazyStringObjectInspector.getPrimitiveWritableObject(LazyStringObjectInspector.java:51)【参考方案2】:

试试

String inumber =  ((org.apache.hadoop.hive.serde2.lazy.LazyString) listOi.getListElement(args[1].get(), i)).getObject().toString();

【讨论】:

谢谢 .. 但错误继续: 原因:java.lang.ClassCastException:java.util.ArrayList 无法在 org.apache.hadoop.hive.serde2.lazy.LazyString 在 org. apache.hadoop.hive.serde2.lazy.objectinspector.primitive.LazyStringObjectInspector.getPrimitiveWritableObject(LazyStringObjectInspector.java:51)【参考方案3】:

这有点晚了,但这可能会解决尝试一次。

在循环中使用以下代码:

public Object evaluate(DeferredObject[] args) throws HiveException ... ... for(int i=0; i<numElem; i++) LazyString inumber = (LazyString) listOi.getListElement(args[1].get(), i); String inumberLS = elemOi.get(inumber); resultlnumerbs.add(prefix + inumberLS); return resultlnumerbs;

在初始化方法中使用返回类型

public ObjectInspector initialize(ObjectInspector[] args) throws UDFArgumentException ... ... return ObjectInspectorFactory.getStandardListObjectInspector(PrimitiveObjectInspectorFactory.javaStringObjectInspector);

【讨论】:

以上是关于Hive GenericUDF 返回数组<String> 错误的主要内容,如果未能解决你的问题,请参考以下文章

使用Java继承UDF类或GenericUDF类给Hive3.1.2编写UDF实现编码解码加密解密并运行在USDP大数据集群

使用Java继承UDF类或GenericUDF类给Hive3.1.2编写UDF实现编码解码加密解密并运行在USDP大数据集群

hive sql - 如何选择 hive 数组列中的前 n 个元素并返回所选数组

Hive 如何实现自定义函数 UDF

Hive 如何实现自定义函数 UDF

Hive:如何检查一个数组的值是不是存在于另一个数组中?