如何在使用 SBT 编译之前进行遮蔽?

Posted

技术标签:

【中文标题】如何在使用 SBT 编译之前进行遮蔽?【英文标题】:how to shade before compile with SBT? 【发布时间】:2017-03-16 18:37:19 【问题描述】:

Our project主要由两部分组成

Build.scala 根项目所在的位置 BuildShaded.scala 其中一些外部依赖项用sbt-assembly 遮蔽。阴影 jar 将通过 unmanagedJars 设置被根项目下的子项目依赖。

问题是如何在编译根项目之前组装阴影项目。否则,根项目将无法编译,因为阴影 jar 中的那些类不可用。

【问题讨论】:

为什么要使用单独的构建来遮蔽外部依赖项?为什么不将它们作为托管依赖项并将它们隐藏在 Build.scala 根目录中? 因为我需要依赖于着色后的类。 “托管依赖项”将在着色之前引入类。 不一定。如果您同时为项目添加了inLibraryinProject 的阴影,它也会摆脱内部依赖项 你是什么意思?您有任何示例或文档吗? 【参考方案1】:

正如我在 cmets 中所说,我会采取不同的路线。如果您将依赖项作为托管的依赖项,您可以在库本身和项目内部对它们进行遮蔽。

我们来看一个例子:

假设我有一个依赖于com.typesafe.config 的项目。我可以在它自己的库中隐藏它,这意味着在 com.typesafe.config 的代码中,以及在消费库中。

你这样定义它:

assemblyShadeRules in assembly ++= Seq(
  ShadeRule.rename("com.typesafe.config.**" -> "my_conf.@1")
    .inLibrary("com.typesafe" % "config" % "1.3.0")
    .inProject
)

这基本上意味着“拿走任何带有com.typesafe.config 的包裹并将其遮蔽到my_conf。”

请注意,我们同时使用了inLibraryinProject。前者的意思是“在com.typesafe.config 中更改包名和对它们的引用”,inProject 的意思是“在我的代码中更改对com.typesafe.config 的所有引用”。

现在,它的输出如下所示:

这就是包内部现在的样子(my_conf 在阴影之前最初是com.typesafe.config):

这是您的代码将引用的包:

【讨论】:

“托管依赖项”似乎不起作用。依赖项目无法使用未找到的阴影类进行编译。 “托管依赖项”是指 Project("core").dependsOn(shaded) ?顺便问一下,inLibrary.inProjectinAll 有什么不同? @manuzhang 不,托管依赖项是指由 SBT 管理的依赖项。您能否展示一个build.sbt 的示例,以便我们可以使用它来调整阴影。 我终于明白了你的意思,并且使用托管依赖项对依赖项目进行着色是可行的。谢谢你拯救了我的一天。 This 最后是我们的构建文件。该方法不是很干净,但我必须在已发布的 pom 文件中手动添加/删除依赖项。 @tomek.xyz 为清楚起见已编辑

以上是关于如何在使用 SBT 编译之前进行遮蔽?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在 sbt 中仅在一个包中遮蔽某些包?

使用 SBT 如何在运行测试之前对插件中的任务进行排序

gitlab ci:sbt 在每个阶段重新编译

如何防止SBT重新编译修改后的.class文件?

如何在 sbt 中运行和编译准确的一项测试?

如何在没有编译/检查的情况下运行“sbt run”?