sbt: найти правильный путь к файлам / папкам в каталоге ресурсов - PullRequest
0 голосов
/ 28 ноября 2018

У меня простая структура проекта:

WordCount|| ------------ проект| ---------------- | --- assembly.sbt|| ------------ ресурсы| ------------------ | ------ Message.txt|| ------------ src| -------------- | --- главная| -------------------- | --- Скала| -------------------------- | --- орг| ------------------------------- | --- апач| ---------------------------------------- | --- искра| ---------------------------------------------- | --Counter.scala|| ------------ build.sbt

вот как выглядит Counter.scala:

package org.apache.spark

object Counter {
    def main(args: Array[String]): Unit = {
        val sc = new SparkContext(new SparkConf())
        val path: String = getClass.getClassLoader.getResource("Message.txt").getPath
        println(s"path = $path")
//      val lines = sc.textFile(path)
//      val wordsCount = lines
//          .flatMap(line => line.split("\\s", 2))
//          .map(word => (word, 1))
//          .reduceByKey(_ + _)
//
//      wordsCount.foreach(println)
    }
}

обратите внимание, что закомментированные строки на самом деле правильные, а переменная path - нет.После создания толстой банки с sbt assembly и запуска ее с spark-submit, чтобы увидеть значение path, я получаю:

path = file:/home/me/WordCount/target/scala-2.11/Counter-assembly-0.1.jar!/Message.txt

вы можете видеть, что назначено pathв папку с jar, и, загадочным образом, за ней следует !/, а затем имя файла Message.txt !!
с другой стороны, когда я нахожусь в папке WordCount, и я запускаю repl sbt console и затем пишу

scala> getClass.getClassLoader.getResource("Message.txt").getPath

Я получил правильный путь (без префикса file:/)

res1: String = /home/me/WordCount/target/scala-2.11/classes/Message.txt

Вопрос:
1 -почему два разных выхода из одной команды?(т.е. getClass.getClassLoader.getResource("...").getPath)2 - как я могу использовать правильный путь, который отображается в консоли, внутри моего исходного файла Counter.scala?


для тех, кто хочет попробовать, вот мой build.sbt:
name := "Counter"

version := "0.1"

scalaVersion := "2.11.8"

resourceDirectory in Compile := baseDirectory.value / "resources"

// allows us to include spark packages
resolvers += "bintray-spark-packages" at "https://dl.bintray.com/spark-packages/maven/"
resolvers += "Typesafe Simple Repository" at "http://repo.typesafe.com/typesafe/simple/maven-releases/"
resolvers += "MavenRepository" at "https://mvnrepository.com/"

libraryDependencies += "org.apache.spark" %% "spark-core" % "2.4.0" % "provided"

и команда spark-submit:

spark-submit --master local --deploy-mode client --class org.apache.spark.Counter /home/me/WordCount/target/scala-2.11/Counter-assembly-0.1.jar

1 Ответ

0 голосов
/ 29 ноября 2018

1 - почему два разных выхода от одной и той же команды?

Под командой я предполагаю, что вы имеете в виду getClass.getClassLoader.getResource("Message.txt").getPath.Поэтому я бы перефразировал вопрос: почему один и тот же вызов метода для classloader getResource(...) возвращает два разных результата в зависимости от sbt console против spark-submit.

Ответ заключается в том, что они используют разные загрузчики классов, каждый из которых имеет разныеCLASSPATH.console использует ваши каталоги как classpath, а spark-submit использует толстый JAR, который включает ресурсы.Когда ресурс найден в JAR, загрузчик классов возвращает URL-адрес JAR , который выглядит как jar:file:/home/me/WordCount/target/scala-2.11/Counter-assembly-0.1.jar!/Message.txt.

Весь смысл использования Apache Spark заключается в распределении некоторой работы между несколькими компьютерами., поэтому я не думаю, что вы хотите видеть локальный путь вашей машины в производстве.

...