2015-11-05 4 views
3

Я пытаюсь запустить собственный класс чтения HDFS в PySpark. Этот класс написан на Java, и мне нужно получить к нему доступ из PySpark, либо из оболочки, либо с помощью spark-submit.Запуск пользовательского класса Java в PySpark

В PySpark я извлекаю JavaGateway из SparkContext (sc._gateway).

Скажем, у меня есть класс:

package org.foo.module 

public class Foo { 

    public int fooMethod() { 
     return 1; 
    } 

} 

Я пытался упаковать его в банку и передать его с опцией --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

Вместо --jars вы должны использовать --packages для импорта пакетов в ваше действие spark-submit.

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().

+0

Использование параметра путь к классам на самом деле работал, и я могу использовать классы в драйвере Spark. Однако, когда я пытаюсь использовать их внутри преобразований, я получаю разные ошибки. Опция 'SparkContext.hadoop *' не подходит для моего использования. Я хочу распараллелить список путей, а затем сделать преобразование, которое читает эти файлы. – hmourit

+0

Внутренние преобразования? Это невозможно (или, по крайней мере, не использовать этот подход). – zero323

+1

Вы также можете добавить его в путь к классам, добавив его в качестве параметра cmd-строки с помощью: '--driver-class-path', если вы не хотите изменять свои файлы конфигурации. –

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 в работоспособный банку и подать искру работу как так

spark-submit --driver-class-path "name_of_your_jar_file.jar" --jars "name_of_your_jar_file.jar" name_of_your_python_file.py 
+1

Также помните, добавляете ли вы несколько банок обязательно используйте синтаксис classpath для -driver-class-path и разделение запятой -jars. – eaubin