akisaya created FLINK-20606:
-------------------------------
Summary: sql client cannot create function using user classes from jar which specified by -j option
Key: FLINK-20606
URL:
https://issues.apache.org/jira/browse/FLINK-20606 Project: Flink
Issue Type: Bug
Components: Connectors / Hive, Table SQL / API, Table SQL / Client
Affects Versions: 1.11.2, 1.12.0, 1.10.2
Reporter: akisaya
I started a sql cli with a hive catalog and specified a user jar file with -j option like this:
{code:java}
bin/sql-client.sh embedded -j /Users/akis/Desktop/flink-func/myfunc.jar
{code}
{color:#FF0000}when i tried to create a custom function using class from myfunc.jar,cli reported ClassNotFoundException.{color}
{code:java}
Flink SQL> use catalog myhive;
Flink SQL> create function myfunc1 as 'me.aki.flink.flinkudf.MyFunc';
[ERROR] Could not execute SQL statement. Reason:
java.lang.ClassNotFoundException: me.aki.flink.flinkudf.MyFunc
{code}
me.aki.flink.flinkudf.MyFunc is the identifier of udf,which defined like this
{code:java}
package me.aki.flink.flinkudf;
import org.apache.flink.table.functions.ScalarFunction;
public class MyFunc extends ScalarFunction {
public String eval(String s) {
return "myfunc_" + s;
}
}
{code}
after walking through the related code, I believe this is a bug caused by wrong classloader
when using a hive catalog, flink will use {color:#FF0000}CatalogFunctionImpl{color} to wrap the function。 The
isGeneric() methed uses {color:#FF0000}Class.forName(String clazzName){color} which will use a current classloader(classloader loads flink/lib) to determine the class。
however with -j option, user jar is set to the ExecutionContext and loaded by another userClassLoader
and the fix can be easy to pass a classloader to the Class.forName method.
{code:java}
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class c = Class.forName(className, true, cl);
{code}
after do such fix and build a new flink dist,create function behaves right
--
This message was sent by Atlassian Jira
(v8.3.4#803005)