【问题标题】:override sbt dependency resolving mechanism (and prevent jar hell)覆盖 sbt 依赖解析机制(并防止 jar hell)
【发布时间】:2014-07-07 12:52:51
【问题描述】:

我们有一个大型的多项目,其中包含我们使用 sbt 构建的许多模块。事实证明,我们在打包不需要的 jar 方面有很多问题。作为解决该问题的第一步,我们创建了一个已使用工件的“全局地图”,其定义如下:

project/Build.scala:

type PartialFunction2[-T1,-T2,+R] = PartialFunction[Tuple2[T1,T2],R]

lazy val dependenciesManager = settingKey[PartialFunction2[String, String, ModuleID]]("a setting containing versions for dependencies. if we only use it to declare dependencies, we can avoid a lot of version collisions.")

build.sbt 在根目录中:

dependenciesManager in Global := {
  case ("ch.qos.logback","logback-classic")  => "ch.qos.logback" % "logback-classic" % "1.1.1"
  case ("com.typesafe","config")             => "com.typesafe" % "config" % "1.2.0"
  case ("com.typesafe","scalalogging-slf4j") => "com.typesafe" %% "scalalogging-slf4j" % "1.1.0"
  case ("com.typesafe.akka",art)             => "com.typesafe.akka" %% art % "2.2.4"
  case ("com.typesafe.play", art)            => "com.typesafe.play" %% art % "2.2.3"
  ...
}

这允许我们在任何模块自己的build.sbt 文件中使用以下语法:

libraryDependencies <++= (dependenciesManager)(dm => Seq(
  dm("com.typesafe.akka","akka-cluster"),
  dm("com.typesafe.akka","akka-contrib"),
  dm("com.typesafe.play","play"),
  dm("ch.qos.logback","logback-classic")
))

其中没有提到依赖版本。 但是,由于传递依赖仍然会导致问题,它只解决了部分问题。

所以我在想,如果我能以某种方式定义一个像上面那样的依赖关系映射,sbt 的解析机制将“通过它”并且它可能会改变所要求的依赖关系。

例如,假设我将logbackslf4j-api 一起使用,我不希望将log4jcommons-logging 的传递依赖添加到类路径,而是像jcl-over-slf4j 这样的桥反而。像上面这样的地图可以解决这个问题。 此外,不会加载不同的版本。并且任何可能已更改其名称的工件(例如 google-collections 现在称为 guavaorg.jboss.netty groupID 已更改为 io.netty)都不会成为问题。

当然,只要给定的依赖项不是所要求的,就应该在屏幕上打印一个警告,并且每当添加新的依赖项时,用户应该手动将其添加到地图中,其中包含所有不存在的传递依赖项然而(或将引发匹配错误)

所以我的问题是,是否有可能实现这样的目标? 如果有,怎么做?

目前关于如何解决问题的想法:

  • 修改ivyReport 任务或update 任务:据我了解,sbt 创建一个 IvyReport xml 文件,根据该文件,ivy 获取请求的工件。我想以某种方式修改update 任务或生成的报告,因此传递依赖项将是我想要的,而不是最初获取的。
  • 使用类似于我们已有的解决方案:仅将映射中的所有ModuleIDs 标记为intransitive(),但(以某种方式)获取它们的依赖项,并获取它们(在映射到想要的文物)

【问题讨论】:

标签: scala dependencies sbt dependency-management


【解决方案1】:

我从未使用过它,但您可以尝试 sbt-one-log 并可能将其用作您尝试解决的其他问题的起点。

【讨论】:

  • 这不是我要找的。该插件只是修改了库依赖项。我宁愿自己做。我正在寻找的是对依赖项的完全控制。日志依赖,只是一个例子......
猜你喜欢
  • 2021-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-28
  • 2013-08-06
  • 2017-05-08
  • 1970-01-01
相关资源
最近更新 更多