Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
UDF不使用外部变量[Java spark]_Java_Apache Spark_Groovyshell - Fatal编程技术网

UDF不使用外部变量[Java spark]

UDF不使用外部变量[Java spark],java,apache-spark,groovyshell,Java,Apache Spark,Groovyshell,我正在尝试执行以下代码 我将数据集作为输入,使用Groovyshell对其执行一些操作,并将结果添加到数据集中的新列中 private static Dataset<Row> addDebitCreditCol(SparkSession sparkSession,Dataset<Row> df,String code){ Script script=new GroovyShell().parse(code); UDF3 rulesExecu

我正在尝试执行以下代码

我将数据集作为输入,使用Groovyshell对其执行一些操作,并将结果添加到数据集中的新列中

private static Dataset<Row> addDebitCreditCol(SparkSession sparkSession,Dataset<Row> df,String code){
        Script script=new GroovyShell().parse(code);
        UDF3 rulesExecutingUDF = (UDF3<Double, String, String, String>) (val1, val2, val3) -> {
            Binding binding = new Binding();
            binding.setVariable("val1",val1);
            binding.setVariable("val2", val2);
            binding.setVariable("val3", val3);
            Object value = script.run();
            return value.toString();
        };
        sparkSession.udf().register("rulesExecutingUDF",rulesExecutingUDF,DataTypes.StringType);
        df=df.withColumn("NEW_COL",callUDF("rulesExecutingUDF",col("val1").,col("val2"),col("val3")));
        return df;
    }
私有静态数据集addDebitCreditCol(SparkSession SparkSession,数据集df,字符串代码){
Script=newgroovyshell().parse(代码);
UDF3规则执行UDF=(UDF3)(val1、val2、val3)->{
绑定=新绑定();
binding.setVariable(“val1”,val1);
binding.setVariable(“val2”,val2);
binding.setVariable(“val3”,val3);
对象值=script.run();
返回值.toString();
};
sparkSession.udf().register(“rulesExecutingUDF”,rulesExecutingUDF,DataTypes.StringType);
df=带列的df(“新列”),callUDF(“规则执行UDF”,列(“val1”)、列(“val2”)、列(“val3”);
返回df;
}
当我执行这段代码时,它抛出一个错误

用户类引发异常:org.apache.spark.SparkException:任务不可序列化。原因:java.io.NotSerializableException:Script1

看起来我不能在UDF中使用外部变量(这里是脚本)。我还有别的选择吗


我试图让这个外部变量以某种方式工作,但它没有工作,我无法找到一个替代UDF的方法来实现这一点。

解决这一问题的简单方法可能是使用一个本身实现可序列化的

public static abstract class BaseClass extends Script implements Serializable {

}
然后将该类用作脚本的超类:

CompilerConfiguration config = new CompilerConfiguration();
config.setScriptBaseClass("stackoverflow.Main.BaseClass"); //use your FQCN
Script script = new GroovyShell(Main.class.getClassLoader(), config).parse(code);

这将使
script
成为可序列化的
实例。如果测试基类的
脚本实例
和可序列化的
脚本实例
,它们都将返回
true

解决此问题的简单方法可能是使用实现可序列化的
脚本实例本身

public static abstract class BaseClass extends Script implements Serializable {

}
然后将该类用作脚本的超类:

CompilerConfiguration config = new CompilerConfiguration();
config.setScriptBaseClass("stackoverflow.Main.BaseClass"); //use your FQCN
Script script = new GroovyShell(Main.class.getClassLoader(), config).parse(code);

这将使
script
成为可序列化的
实例。如果测试基类的
脚本实例
和可序列化的
脚本实例
,它们都将返回
true

是否可以尝试移动
脚本脚本=新GroovyShell().parse(code)在udf内部?我之前才这么做。但问题是,对于制作新Groovyshell所需的每一条记录,它都会产生一些问题。这就是为什么我必须把它从循环中去掉在udf内部?我之前才这么做。但问题是,对于制作新Groovyshell所需的每一条记录,它都会产生一些问题。这就是为什么我必须把这个从循环中去掉。