Scala UDF作为外部Jars

时间:2018-02-21 10:06:47

标签: scala apache-spark apache-spark-sql user-defined-functions scala-reflect

我有一个对象,我写了我的Udf

package com.udf.sample
object UDFDetails {
  def udfIndexOf = (inputValue: String, matchCriteria: String) => {
  inputValue.toUpperCase().indexOf(matchCriteria)
}

}

如果我直接注册,那么我将返回类型

org.apache.spark.sql.expressions.UserDefinedFunction = UserDefinedFunction(<function2>,IntegerType,Some(List(StringType, StringType)))

现在这是一个不同的模块,我希望在我的Spark处理中使用这个udf。

所以,我使用反射来使用这个udf并试图使用这个

来注册它
def registerUdfFunc() = {
     val udfDf = getDataFrame("UDF_TABLE")
     udfDf.collect.foreach { x =>
     registerDynamicUDF(x.getString(x.fieldIndex("className")), x.getString(x.fieldIndex("functionName")), x.getString(x.fieldIndex("udfName")));
}


private def registerDynamicUDF(objectName: String, udfFunction: String, udfName: String) = 
{
 val runtimeMirror = universe.runtimeMirror(getClass.getClassLoader)
 val moduleSymbol = runtimeMirror.moduleSymbol(Class.forName(objectName))  
 var targetMethod = moduleSymbol.typeSignature.members.filter(x => 
 x.isMethod && x.name.toString == udfFunction).head.asMethod
 var function = runtimeMirror.reflect(runtimeMirror.reflectModule(moduleSymbol).instance).reflectMethod(targetMethod)()
 SparkSession.builder.getOrCreate().udf.register(udfName, function)
 } 

我已经在表中存储了对象名称,UdfName(用于注册),fucntionName,我从中创建了数据帧并进行迭代。 现在当我使用

SparkSession.builder.getOrCreate().udf.register(udfName, function) 

它给了我错误,说不能用任何类型

注册udf
 (name: String,udf:org.apache.spark.sql.expressions.UserDefinedFunction)org.apache.spark.sql.expressions.UserDefinedFunction cannot be applied to (String, Any) spark.udf.register("index",function)

如果我尝试将其强制转换为UserDefinedFunction,它会给我一个classcast异常。 我该怎么做,有什么想法吗?

0 个答案:

没有答案