遮蔽第三方 类

Shading over third party classes

我目前面临将 uber-jar 部署到 Spark Streaming 应用程序的问题,其中存在不同版本的一致 JAR,导致 spark 抛出 运行 次异常。有问题的图书馆是 TypeSafe Config.

在尝试了很多事情之后,我的解决方案是推迟对提供的依赖项进行着色,这样它就不会在 运行 时与 Spark 提供的 JAR 发生冲突。

因此,我查看了 sbt-assembly 的文档,在阴影下,我看到了以下示例:

assemblyShadeRules in assembly := Seq(
      ShadeRule.rename("org.apache.commons.io.**" -> "shadeio.@1")
      .inLibrary("commons-io" % "commons-io" % "2.4", ...).inProject
)

试图遮盖 com.typesafe.config,我尝试将以下解决方案应用于我的 build.sbt

assemblyShadeRules in assembly := Seq(
  ShadeRule.rename("com.typesafe.config.**" -> "shadeio.@1").inProject
)

我假设它应该重命名我项目中对 TypeSafe Config 的任何引用。但是,这是行不通的。它匹配我项目中的多个 类 并导致它们从 uber jar 中删除。我在尝试 运行 sbt assembly:

时看到了这个
Fully-qualified classname does not match jar entry:
  jar entry: ***/Identifier.class
  class name: **/Identifier.class
Omitting ***/OtherIdentifier.class.
Fully-qualified classname does not match jar entry:
  jar entry: ***\SparkBaseJobRunner$$anonfun.class
  class name: ***/SparkBaseJobRunner$$anonfun.class

我还尝试使用:

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

这确实完成了 uber JAR 的组装过程,但没有达到预期的 运行 时间效果。

我不确定我是否完全理解着色对我使用 sbt 的构建过程的影响。

如何在我的项目中遮蔽对 com.typesafe.config 的引用,以便当我在 运行 时调用库时,Spark 将加载我的遮蔽库并避免由版本控制引起的冲突?

我正在 运行ning sbt-assembly v0.14.1

原来 this was a bug in sbt-assembly where shading was completely broken on Windows. 这导致源文件从超级 JAR 中删除,并且测试失败,因为上述 类 不可用。

我创建了一个 pull request to fix this。从 SBT 的 0.14.3 版本开始,着色功能可以正常工作。您需要做的就是更新到plugins.sbt中的相关版本:

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

为了隐藏项目中的特定 JAR,您执行以下操作:

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

这将重命名要打包到 my_conf 中的 com.typesafe.config 程序集。然后,您可以在程序集上使用 jar -tf 查看此内容(为简洁起见,省略了不相关的部分):

***> jar -tf myassembly.jar
my_conf/
my_conf/impl/
my_conf/parser/

编辑

我写了一个 blog post 描述问题和导致它的过程,以供有兴趣进行更深入解释的任何人使用。