Я новичок в Scala и SBT, и в попытке узнать что-то новое, я пытаюсь пробежаться по книге " Создание механизма рекомендаций с помощью Scala ". Библиотеки примеров, упомянутые в книге, теперь были заменены более поздними версиями или в некоторых случаях, казалось бы, заменены другими методами (от casbah до драйвера Mongo Scala). Это привело к тому, что я создал несколько потенциально неправильных файлов сборки SBT. С моим начальным файлом сборки у меня было;

name := "BuildingScalaRecommendationEngine"

scalaVersion := "2.12.1"

version :="1.0"

libraryDependencies += "org.apache.spark" %  "spark-mllib_2.11" % "2.1.0"

libraryDependencies += "org.apache.spark" % "spark-streaming_2.11" % "2.1.1"

libraryDependencies += "org.mongodb.scala" %% "mongo-scala-driver" % "2.1.0"

libraryDependencies += "org.apache.kafka" % "kafka_2.12" % "0.10.2.0"

libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.5.1" 

Это приводило к ошибке сборки вроде;

[error] Modules were resolved with conflicting cross-version suffixes in {file:/C:/Dev/learning/scala/Tutorial/src/}src:

[error]    org.scala-lang.modules:scala-xml _2.11, _2.12
java.lang.RuntimeException: Conflicting cross-version suffixes in: org.scala-lang.modules:scala-xml

Я попытался воспользоваться некоторыми примерами, предложенными на этой ссылкой, которую я нашел в беседе с Гиттером < a href = "https://gitter.im/sbt/sbt/archives/2016/11/07" rel = "nofollow noreferrer"> здесь . Однако все эти предложения были немного выше моего понимания.

Мне удалось обойти ошибку, используя, в основном, метод проб и ошибок, внеся изменения в файл сборки, чтобы он выглядел следующим образом;

name := "BuildingScalaRecommendationEngine"

scalaVersion := "2.12.1"

version :="1.0"

libraryDependencies += "org.apache.spark" %  "spark-mllib_2.11" % "2.1.0" excludeAll(
    ExclusionRule(organization = "org.scala-lang.modules")
  )

libraryDependencies += "org.apache.spark" % "spark-streaming_2.11" % "2.1.1" excludeAll(
    ExclusionRule(organization = "org.scala-lang.modules")
  )

libraryDependencies += "org.mongodb.scala" %% "mongo-scala-driver" % "2.1.0" excludeAll(
    ExclusionRule(organization = "org.scala-lang.modules")
  )

libraryDependencies += "org.apache.kafka" % "kafka_2.12" % "0.10.2.0" excludeAll(
    ExclusionRule(organization = "org.scala-lang.modules")
  )

libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.5.1" excludeAll(
    ExclusionRule(organization = "org.scala-lang.modules")
  )

Могу ли я что-то сделать с моим исходным файлом сборки, чтобы обойти эту ошибку?

Существует ли сочетание значений библиотечных зависимостей, которое вызывает это в первую очередь?

Я стремлюсь лучше понять Scala и SBT, чтобы преодолеть это, но пока что это несколько расстраивает.

2
Mr Moose 28 Май 2017 в 05:31

2 ответа

Лучший ответ

Tl; dr: вы не можете использовать Scala 2.12, потому что Spark еще не поддерживает его, и вам также нужно использовать %% при указании зависимостей, чтобы избежать проблем с неправильными двоичными версиями. Читайте ниже для более подробного объяснения.

Версии Scala, такие как 2.x, являются двоично-несовместимыми, поэтому все библиотеки должны компилироваться отдельно для каждого такого выпуска (2.10, 2.11 и 2.12 являются используемыми в настоящее время, хотя 2.10 находится на пути к тому, чтобы быть устаревшим). Вот что такое _2.12 суффикс _2.11.

Естественно, вы не можете использовать библиотеки, скомпилированные для другой версии Scala, чем та, которую вы используете в настоящее время. Таким образом, если вы установите scalaVersion, скажем, 2.12.1, вы не сможете использовать библиотеки с именами с суффиксом _2.11. Вот почему можно написать "groupName" % "artifactName" и "groupName" %% "artifactName": в последнем случае, когда вы используете двойной знак процента, текущая двоичная версия Scala будет автоматически добавлена к имени:

scalaVersion := "2.12"

"groupName" %% "artifactName" % "version"
    == 
"groupName" % "artifactName_2.12" % "version"

Итак, в 99% случаев вы хотите установить версию Scala один раз, а затем использовать оператор %% для указания библиотек Scala.

Однако в вашем случае проблема в том, что вы хотите использовать Scala 2.12, но вы пытаетесь использовать Spark, скомпилированную для Scala 2.11. В идеальном мире правильным решением было бы использовать %% для всех ваших зависимостей, поэтому будут использоваться их 2.12-совместимые артефакты, однако артефакты Spark еще не опубликованы для Scala 2.12 (некоторые проблемы препятствуют стабильности Spark на 2.12, насколько я помню). Поэтому вам следует изменить версию Scala на 2.11.11 (последняя версия Scala в ветви 2.11), а затем избавиться от суффиксов _2.11 / _2.12 в именах артефактов и использовать {{X3 }} вместо. Тогда это должно работать.

3
Vladimir Matveev 28 Май 2017 в 03:36

Это исключение конфликта версий


Здесь вы используете spark-библиотеки с scala 2.11 «spark-streaming_2.11», поэтому измените версию scala с 2.12.1 на 2.11.X, чтобы избежать исключения конфликта версий.

Используйте следующий тип sbt

name := "BuildingScalaRecommendationEngine"

scalaVersion := "2.11.6"

version :="1.0"

libraryDependencies += "org.apache.spark" %  "spark-mllib_2.11" % "2.1.0"

libraryDependencies += "org.apache.spark" % "spark-streaming_2.11" % "2.1.1"

libraryDependencies += "org.mongodb.scala" %% "mongo-scala-driver" % "2.1.0"

libraryDependencies += "org.apache.kafka" % "kafka_2.12" % "0.10.2.0"

libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.5.1"
0
Nilesh Shinde 1 Окт 2018 в 06:50