6

我正在尝试在 PySpark 中运行自定义 HDFS 阅读器类。这个类是用 Java 编写的,我需要从 PySpark 访问它,无论是从 shell 还是使用 spark-submit。

在 PySpark 中,我从 SparkContext ( sc._gateway) 中检索 JavaGateway。

假设我有一堂课:

package org.foo.module

public class Foo {

    public int fooMethod() {
        return 1;
    }

}

我试图将它打包到一个 jar 中并通过--jar选项传递给 pyspark 然后运行:

from py4j.java_gateway import java_import

jvm = sc._gateway.jvm
java_import(jvm, "org.foo.module.*")

foo = jvm.org.foo.module.Foo()

但我得到了错误:

Py4JError: Trying to call a package.

有人可以帮忙吗?谢谢。

4

4 回答 4

9

在 PySpark 中尝试以下操作

from py4j.java_gateway import java_import
java_import(sc._gateway.jvm,"org.foo.module.Foo")

func = sc._gateway.jvm.Foo()
func.fooMethod()

确保您已将 Java 代码编译成可运行的 jar 并像这样提交 spark 作业

spark-submit --driver-class-path "name_of_your_jar_file.jar" --jars "name_of_your_jar_file.jar" name_of_your_python_file.py
于 2016-03-01T14:12:38.370 回答
2

您描述的问题通常表明org.foo.module不在驱动程序 CLASSPATH 上。一种可能的解决方案是使用spark.driver.extraClassPath添加您的 jar 文件。例如,它可以设置在命令行参数中conf/spark-defaults.conf或作为命令行参数提供。

附带说明:

  • 如果您使用的类是自定义输入格式,则不需要使用 Py4j 网关。您可以简单地使用SparkContext.hadoop*/SparkContext.newAPIHadoop*方法。

  • 使用java_import(jvm, "org.foo.module.*")看起来是个坏主意。一般来说,您应该避免在 JVM 上进行不必要的导入。它不公开是有原因的,你真的不想惹它。特别是当您以一种使此导入完全过时的方式访问时。所以放弃java_import并坚持下去jvm.org.foo.module.Foo()

于 2015-11-06T00:35:51.740 回答
0

If you run PySpark locally in IDE (PyCharm, etc.), to use custom classes in a jar, you can put the jar into $SPARK_HOME/jars, it will be added to class path to run Spark, check code snippet in $SPARK_HOME/bin/spark-class2.cmd for details.

于 2021-01-12T03:08:50.730 回答
-1

而不是--jars您应该使用--packages将包导入到您的spark-submit操作中。

于 2015-11-05T12:43:19.930 回答