【问题标题】:How to exclude transitive dependency in Sbt ( in context of assembly plugin )?如何排除 Sbt 中的传递依赖(在程序集插件的上下文中)?
【发布时间】:2016-02-01 12:41:21
【问题描述】:

我有两个 Sbt 项目,my-commonsmy-service

我的公地

依赖关系

libraryDependencies ++= Seq(
  "nz.ac.waikato.cms.weka" % "attributeSelectionSearchMethods" % "1.0.7",
  "de.bwaldvogel" % "liblinear" % "1.95"
  "io.dropwizard.metrics" % "metrics-graphite" % "3.1.2",
  "com.github.nscala-time" %% "nscala-time" % "2.2.0",
  "org.apache.hive" % "hive-jdbc" % "1.1.0-cdh5.4.5",
  "org.apache.hadoop" % "hadoop-common" % "2.6.0-cdh5.4.5",
  "org.apache.hadoop" % "hadoop-hdfs" % "2.6.0-cdh5.4.5"
)

我的服务:

依赖关系

libraryDependencies ++= {
  Seq(
    "ch.qos.logback" % "logback-classic" % "1.0.13",
    "io.spray" %% "spray-httpx" % "1.3.3",
    "io.spray" %% "spray-json" % "1.3.2",
    "io.spray" %% "spray-can" % "1.3.3",
    "io.spray" %% "spray-routing" % "1.3.3",
    "io.spray" %% "spray-testkit" % "1.3.3" % "test",
    "com.typesafe.akka" %% "akka-actor" % "2.3.9",
    "com.typesafe.akka" %% "akka-testkit" % "2.3.9" % "test",
    "org.specs2" %% "specs2-core" % "2.3.11" % "test",
    "org.json4s" %% "json4s-native" %  "3.2.11",
    "org.json4s" %% "json4s-ext" %  "3.2.11",
    "org.mockito" % "mockito-all" % "1.8.4" % "test",
    "com.mycommon.projects" % "my-commons" % "1.0.+"
  )

我正在使用程序集 sbt 插件

   addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2")

我在 sbt 程序集上遇到错误:

at java.lang.Thread.run(Thread.java:745)
[error] (*:assembly) deduplicate: different file contents found in the following:
[error] /home/me/.ivy2/cache/org.slf4j/slf4j-api/jars/slf4j-api-1.7.7.jar:META-INF/maven/org.slf4j/slf4j-api/pom.properties
[error] /home/me/.ivy2/cache/com.twitter/parquet-hadoop-bundle/jars/parquet-hadoop-bundle-1.5.0-cdh5.4.5.jar:META-INF/maven/org.slf4j/slf4j-api/pom.properties

我试图从构建中排除这些库,但没有成功。

libraryDependencies ~= { _ map {
  case m if m.organization.startsWith("org.apache") || m.organization.startsWith("com.twitter") || m.name.contains("parquet") =>
   m.exclude("org.slf4j","slf4j-api").
   exclude("org.slf4j","slf4j-log4j12")
   case m => m
 }}

可能我做错了什么......我该如何解决这个依赖地狱?

【问题讨论】:

  • 你能提供你的 Build.scala 和项目层次结构吗?
  • 这是 build.sbt 的部分。这两个项目不是分层的
  • 那么为什么my-service 依赖于my-common? "com.mycommon.projects" % "my-commons" % "1.0.+"
  • 这两个项目是否在同一个目录中?每个文件夹不同?

标签: scala sbt


【解决方案1】:

当 sbt-assembly 合并包时,有时会因为选择的策略而发生冲突。由于这两个文件名称相同但内容不同,因此 sbt-assembly 不能做任何事情。这是默认策略:deduplicate

可能最好的解决方案是指定另一个merge strategy,在这种情况下,first 将是最好的选择。

在您的assembly.sbt(在根目录中)(不是project/assembly.sbt)中输入以下内容:

import AssemblyKeys._ 

assemblySettings

mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) =>
  {
    case PathList("META-INF", "maven", "org.slf4j", "slf4j-api", "pom.properties") => MergeStrategy.first
    case PathList("META-INF", "maven", "org.slf4j", "slf4j-api", "pom.xml") => MergeStrategy.first
    case x => old(x)
  }
}

【讨论】:

  • 您好,非常感谢。我对 scala 很陌生...您能添加一个示例吗
  • 我试图在本地复制您的项目,以提供准确的 sn-p,但我做不到。我真的需要了解您的项目如何,文件夹结构和文件(尽管不需要包含代码源)。例如,依赖 "com.mycommon.projects" % "my-commons" % "1.0.+" 对我来说没有意义。
  • 如果您可以使用此信息更新答案,也许我可以为您提供更多帮助
  • 当然,我使用 my-commons 作为单独的 git 存储库。我正在使用 sbt 包 publishLocal(或 publishM2)构建它。然后我正在构建我的服务 jar
【解决方案2】:

在您的情况下,文件存在不同的内容,因此无法与 SBT 程序集插件合并。

两种可能的方法

方法一:

使用程序集插件的合并过滤器来指定要保留哪些文件,例如

val sharedMergeStrategy: (String => MergeStrategy) => String => MergeStrategy =
  (old: (String) => MergeStrategy) => {
    case x if x.startsWith("META-INF/ECLIPSEF.RSA") => MergeStrategy.last
    case x if x.startsWith("META-INF/mailcap") => MergeStrategy.last
    case x if x.endsWith("plugin.properties") => MergeStrategy.last
    case x => old(x)
  }

方法二:

请参阅http://www.scala-sbt.org/0.13/docs/Library-Management.html#Exclude+Transitive+Dependencies,了解如何排除传递依赖。

【讨论】:

  • 谢谢,我试过排除,但没有奏效。您能否说明我应该在 buid.sbt 中定义和使用什么,使用合并过滤器的插件。
  • 这在很大程度上取决于您的要求。首先,总体上对合并策略充满信心。其次,当涉及到合并冲突时,添加一条规则,丢弃错误的文件并随后执行此步骤,直到不再出现冲突。如果这不能产生解决方案,请考虑传递依赖关系并尝试通过丢弃那些不需要的依赖关系来预先消除它们。
  • 除此之外:为什么您肯定需要 fat-jar 或 uber-jar?不能用scala-sbt.org/sbt-native-packager/archetypes(Native Packager)打包所有东西吗?
猜你喜欢
  • 2018-08-19
  • 2021-07-26
  • 1970-01-01
  • 2013-04-22
  • 2014-06-30
  • 2014-04-25
  • 2015-09-08
  • 2019-01-22
  • 2018-07-06
相关资源
最近更新 更多