Как включить файлы python и Scala все вместе в файл jar с использованием sbt?

#scala #apache-spark #pyspark #sbt

#scala #apache-spark #pyspark #sbt

Вопрос:

Цель:

Создайте единый jar с файлами scala и python и передайте этот jar в pyspark, чтобы иметь возможность вызывать файлы scala и python. Основное выполнение будет выполняться в файлах python, которые будут использовать библиотеки scala внутри с помощью py4j.

Как включить файлы python / пакет в файл jar вместе с файлами scala с использованием SBT?

Структура проекта (открыта для изменения на все, что работает)

 parent_project
|
|-- child_project
    |
    |-- src
        |
        |-- main
            |
            |-- scala
                |
                |-- com.my_org.child_project
                    |
                    |-- s_file_1.scala
                    |-- s_file_2.scala
            |-- python
                |
                |-- foo
                    |
                    |-- p_file_1.py
                    |-- p_file_2.py
    |-- build.sbt                      -- for child project
|-- build.sbt                          -- for parent project
  

Пример build.sbt (для дочернего проекта)

 name := "child_project"
version := "1.0.0"
scalaVersion := "2.11.1"
val sparkVersion = "2.4.4"

lazy val dependencies = new {}

libraryDependencies   = Seq()
  

Пример build.sbt (для родительского проекта)

 lazy val child_project = project.in(file("parent_project/child_project"))
  .dependsOn(parent % "provided->provided;compile->compile;test->test;runtime->runtime")
  .settings(
    name := "child_project",
    organization := "com.my_org",
    unmanagedSourceDirectories in Compile  = file("/parent_project/child_project/src/main/python"),
    includeFilter in (Compile, unmanagedSources) := "*.scala" || "*.java" || "*.py"
    assemblySettings
  )
  

Версия SBT = 0.13.16

Команда SBT для сборки jar

 "project child_project" assembly
  

Конкретные вопросы:

  1. Возможно ли включить пакет как python, так и scala-код в один jar?
  2. Возможно ли предоставить этот jar в pyspark и получить доступ к файлам python и scala из него?
  3. Есть предложения / обходные пути / лучшие варианты для достижения цели?

Ответ №1:

Решение, которое сразу приходит мне на ум, было бы поместить .py файлы в main/resources каталог. Это больше похоже на взлом, но, возможно, это то, что вы хотите (особенно для файлов python).

Гораздо лучшим решением было бы определить main/python в качестве исходного каталога, как описано в Добавить дополнительный исходный каталог:

sbt собирает sources из unmanagedSourceDirectories , который по умолчанию состоит из scalaSource и javaSource . Добавьте каталог в unmanagedSourceDirectories в соответствующей конфигурации, чтобы добавить исходный каталог. Например, добавить extra-src в качестве дополнительного каталога, содержащего основные источники,

 Compile / unmanagedSourceDirectories  = baseDirectory.value / "extra-src"
  

Это было бы следующим в вашем build.sbt :

 Compile / unmanagedSourceDirectories  = baseDirectory.value / "python"
  

Комментарии:

1. Пробовал это, но не работает. Я обновил вопрос, чтобы отразить этот параметр (sbt для родительского проекта). Даже пытался сохранить файл python в scala исходном коде, это тоже не работает. Также добавлена версия SBT (0.13.16), о которой идет речь.

2. Повторил чистую сборку, удалив целевой каталог, обновив sbt и перезапустив оболочку sbt. Теперь, похоже, он соблюдает настройки, но терпит неудачу с ошибками компиляции, очевидно, при сборке файлов python. Можно ли пропустить компиляцию файлов python?

3. Каждый раз, когда вы меняете, build.sbt вам приходится перезапускать оболочку sbt. Где файлы python?

4. Спасибо! Файлы python находятся в каталоге /parent_project / child_project/src/main /python.

5. Помечено parent_project/child_project/src/main/python как папка ресурсов. SBT в основном ведет себя странно. Иногда это помещает файлы python в jar, иногда нет. В любом случае, это подход, который я выбрал. Отметьте пакет python как дополнительный ресурс, используя следующее в определении проекта в build.sbt (родительский) unmanagedResourceDirectories in Compile = file("/parent_project/child_project/src/main/python")