Comment travailler efficacement avec SBT, Spark et les dépendances" fournies"?

je construis une application Apache Spark dans Scala et J'utilise SBT pour la construire. Voici la chose:

  1. quand je développe sous IntelliJ IDEA, je veux que les dépendances à L'étincelle soient incluses dans le chemin de classe (je lance une application régulière avec une classe principale)
  2. quand j'empaquette l'application (grâce au plugin sbt-assembly), je fais vous voulez Étincelle dépendances à être inclus dans ma graisse JAR
  3. quand je fais des tests unitaires sbt test, je veux Étincelle dépendances à être inclus dans le classpath (de même que le #1, mais à partir de la SBT)

pour correspondre À la contrainte n ° 2, je suis déclarant Étincelle dépendances provided:

libraryDependencies ++= Seq(
  "org.apache.spark" %% "spark-streaming" % sparkVersion % "provided",
  ...
)

Ensuite, sbt-documentation de l'Assemblée suggère d'ajouter la ligne suivante pour inclure les dépendances pour les tests unitaires (contrainte #3):

run in Compile <<= Defaults.runTask(fullClasspath in Compile, mainClass in (Compile, run), runner in (Compile, run))

ce qui me laisse avec la contrainte #1 n'étant pas remplie, c'est-à-dire que je ne peux pas exécuter la demande dans IntelliJ idée comme les dépendances D'étincelle ne sont pas captées.

avec Maven, j'utilisais un profil spécifique pour construire le bocal uber. De cette façon, je déclarais les dépendances Spark comme des dépendances régulières pour le profil principal (IDE et tests unitaires) tout en les déclarant comme provided pour l'emballage du pot de graisse. Voir https://github.com/aseigneurin/kafka-sandbox/blob/master/pom.xml

Quelle est la meilleure façon d'y parvenir avec SBT?

18
demandé sur Sean Glover 2016-04-06 00:58:19

6 réponses

(répondant à ma propre question par une réponse que j'ai reçue d'une autre chaîne...)

pour pouvoir exécuter L'application Spark à partir D'IntelliJ IDEA, il vous suffit de créer une classe principale dans le src/test/scala répertoire (test, pas main). IntelliJ va ramasser le provided dépendances.

object Launch {
  def main(args: Array[String]) {
    Main.main(args)
  }
}

Merci Matthieu Blanc pour le pointage.

13
répondu Alexis Seigneurin 2017-03-18 23:33:46

Vous devez faire fonctionner L'IntellJ.

l'astuce principale ici est de créer un autre sous-projet qui dépendra du sous-projet principal et aura toutes ses bibliothèques fournies dans la compilation scope. Pour ce faire, j'Ajoute les lignes suivantes à construire.sbt:

lazy val mainRunner = project.in(file("mainRunner")).dependsOn(RootProject(file("."))).settings(
  libraryDependencies ++= spark.map(_ % "compile")
)

maintenant je rafraîchis le projet IDEA et je modifie légèrement la configuration d'exécution précédente pour qu'il utilise classpath du nouveau module mainRunner:

intellj

travaux parfaitement pour moi.

Source: https://github.com/JetBrains/intellij-scala/wiki/%5BSBT%5D-How-to-use-provided-libraries-in-run-configurations

3
répondu Atais 2018-03-01 16:17:03

la façon La plus simple d'ajouter provided dépendances pour déboguer une tâche avec IntelliJ est:

  • clic Droit src/main/scala
  • Sélectionner Mark Directory as...>Test Sources Root

Cela dit IntelliJ pour traiter src/main/scala comme un dossier test pour lequel il ajoute toutes les dépendances étiquetées comme provided pour n'importe quel config (debug/run).

chaque fois que vous faites un rafraîchissement SBT, refaites cette étape comme IntelliJ réinitialisera le dossier dans un dossier source régulier.

2
répondu Martin Tapp 2017-09-18 13:22:16

vous ne devriez pas regarder SBT pour un réglage D'idée spécifique. Tout d'abord, si le programme est censé être exécuté avec spark-submit, comment l'exécutez-vous sur IDEA ? Je suppose que vous exécuteriez en standalone dans IDEA, tout en l'exécutant à travers spark-submit normalement. Si c'est le cas, ajoutez manuellement les bibliothèques spark dans IDEA, en utilisant File|Project Structure|Libraries. Vous verrez toutes les dépendances listées à partir de SBT, mais vous pouvez ajouter des artefacts jar/maven arbitraires en utilisant le + (plus) signer. Cela devrait faire l'affaire.

0
répondu Roberto Congiu 2016-04-05 22:21:10

pourquoi ne pas contourner sbt et ajouter manuellement spark-core et spark-streaming comme bibliothèques à vos dépendances de module?

  • ouvrez la boîte de dialogue Structure du projet (par exemple, PPC;).
  • dans le volet de gauche de la boîte de dialogue, sélectionnez Modules.
  • Dans le volet de droite, sélectionnez le module d'intérêt.
  • Dans la partie droite de la boîte de dialogue, sur la page du Module, sélectionnez l'onglet Dépendances.
  • dans L'onglet Dépendances, cliquez ajouter et sélectionnez Bibliothèque.
  • dans la boîte de dialogue Choisir les Bibliothèques, sélectionnez nouvelle bibliothèque, à partir de maven
  • trouver spark-core. Exorg.apache.spark:spark-core_2.10:1.6.1
  • Profit

https://www.jetbrains.com/help/idea/2016.1/configuring-module-dependencies-and-libraries.html?origin=old_help#add_existing_lib

-1
répondu Jean-Marc S. 2016-04-06 05:54:29

une solution basée sur la création d'un autre sous-projet pour exécuter le projet localement est décrite ici.

en gros, vous devez modifier le build.sbt le fichier avec le code suivant:

lazy val sparkDependencies = Seq(
  "org.apache.spark" %% "spark-streaming" % sparkVersion
)

libraryDependencies ++= sparkDependencies.map(_ % "provided")

lazy val localRunner = project.in(file("mainRunner")).dependsOn(RootProject(file("."))).settings(
   libraryDependencies ++= sparkDependencies.map(_ % "compile")
)

puis exécutez le nouveau sous-projet localement avec Use classpath of module: localRunner sous la Configuration Run.

-1
répondu bertslike 2017-02-09 11:35:03