Я заметил, что при попытке собрать толстый jara для playframework 2.7 с play-ws (сборка sbt) возникают дубликаты зависимостей. Я получаю много ошибок, связанных с javax.activation-api и shaded-asynchttpclient, например,
[error] deduplicate: different file contents found in the following:
[error] /home/user/.cache/coursier/v1/https/repo1.maven.org/maven2/javax/activation/javax.activation-api/1.2.0/javax.activation-api-1.2.0.jar:javax/activation/UnsupportedDataTypeException.class
[error] /home/user/.cache/coursier/v1/https/repo1.maven.org/maven2/com/typesafe/play/shaded-asynchttpclient/2.0.6/shaded-asynchttpclient-2.0.6.jar:javax/activation/UnsupportedDataTypeException.class
. Проблема заключается в play-ws, без которого сборка sbt выполняется правильно. Единственное место в моем коде, где я явно использую javax - это внедрение зависимостей. Использование guice вместо этого дает тот же результат. Вот мой build.sbt (который основан на https://www.playframework.com/documentation/2.7.x/Deploying)
name := "My-App"
version := "1.0"
scalaVersion := "2.11.12"
lazy val root = (project in file(".")).enablePlugins(PlayScala)
scalaSource in ThisScope := baseDirectory.value
mainClass in assembly := Some("play.core.server.ProdServerStart")
fullClasspath in assembly += Attributed.blank(PlayKeys.playPackageAssets.value)
libraryDependencies ++= Seq(
ws,
specs2 % Test,
"com.typesafe.play" %% "play-json" % "2.7.4",
"com.typesafe.play" %% "play-slick" % "4.0.2",
"com.typesafe.play" %% "play-slick-evolutions" % "4.0.2",
"com.typesafe" % "config" % "1.4.0",
"org.mindrot" % "jbcrypt" % "0.4",
"mysql" % "mysql-connector-java" % "8.0.17",
"org.mindrot" % "jbcrypt" % "0.4",
"com.iheart" %% "ficus" % "1.4.7",
"com.typesafe.scala-logging" % "scala-logging_2.11" % "3.9.0"
)
assemblyMergeStrategy in assembly := {
case manifest if manifest.contains("MANIFEST.MF") =>
// We don't need manifest files since sbt-assembly will create
// one with the given settings
MergeStrategy.discard
case referenceOverrides if referenceOverrides.contains("reference-overrides.conf") =>
// Keep the content for all reference-overrides.conf files
MergeStrategy.concat
case x =>
// For all the other files, use the default sbt-assembly merge strategy
val oldStrategy = (assemblyMergeStrategy in assembly).value
oldStrategy(x)
}