我正在尝试在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.
有人可以帮忙吗?感谢。
答案 0 :(得分: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()
。
答案 1 :(得分:2)
在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
答案 2 :(得分:0)
而不是--jars
您应该使用--packages
将包导入spark-submit
行动。
答案 3 :(得分:0)
如果你在IDE中本地运行PySpark(PyCharm等),要在jar中使用自定义类,你可以将jar放入$SPARK_HOME/jars,它会被添加到类路径中运行Spark,查看代码片段在 $SPARK_HOME/bin/spark-class2.cmd 中了解详细信息。