我正在尝试用参数实现配置单元UDF,因此我正在扩展GenericUDF类。
问题是我的UDF在StringDatatype上工作,但如果我在其他数据类型上运行,它会抛出错误。我希望UDF无论数据类型如何都能运行。
有人能告诉我以下代码出了什么问题吗。
@Description(name = "Encrypt", value = "Encrypt the Given Column", extended = "SELECT Encrypt('Hello World!', 'Key');")
public class Encrypt extends GenericUDF {
StringObjectInspector key;
StringObjectInspector col;
@Override
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
if (arguments.length != 2) {
throw new UDFArgumentLengthException("Encrypt only takes 2 arguments: T, String");
}
ObjectInspector keyObject = arguments[1];
ObjectInspector colObject = arguments[0];
if (!(keyObject instanceof StringObjectInspector)) {
throw new UDFArgumentException("Error: Key Type is Not String");
}
this.key = (StringObjectInspector) keyObject;
this.col = (StringObjectInspector) colObject;
return PrimitiveObjectInspectorFactory.javaStringObjectInspector;
}
@Override
public Object evaluate(DeferredObject[] deferredObjects) throws HiveException {
String keyString = key.getPrimitiveJavaObject(deferredObjects[1].get());
String colString = col.getPrimitiveJavaObject(deferredObjects[0].get());
return AES.encrypt(colString, keyString);
}
@Override
public String getDisplayString(String[] strings) {
return null;
}
}
错误
java.lang.ClassCastException:org.apache.hadoop.hive.serde2.objectinsector.primitive.JavaIntObjectInspector无法强制转换为org.apache.haoop.hive-serde2.objectINSector.prititive.StringObjectInspector
我建议您将StringObjectInspector col
替换为PrimitiveObjectInspector col
和相应的强制转换this.col = (PrimitiveObjectInspector) colObject
。然后有两种方法:
首先是处理所有可能的Primitive类型,比如这个
switch (((PrimitiveTypeInfo) colObject.getTypeInfo()).getPrimitiveCategory()) {
case BYTE:
case SHORT:
case INT:
case LONG:
case TIMESTAMP:
cast_long_type;
case FLOAT:
case DOUBLE:
cast_double_type;
case STRING:
everyting_is_fine;
case DECIMAL:
case BOOLEAN:
throw new UDFArgumentTypeException(0, "Unsupported yet");
default:
throw new UDFArgumentTypeException(0,
"Unsupported type");
}
}
另一种方法,是使用PrimitiveObjectInspectorUtils.getString
方法:
Object colObject = col.getPrimitiveJavaObject(deferredObjects[0].get());
String colString = PrimitiveObjectInspectorUtils.getString(colObject, key);
它只是像伪代码一样的例子。希望能有所帮助。