遮蔽第三方课程

时间:2016-04-04 15:26:41

标签: scala sbt sbt-assembly

我目前面临着将一个超级jar部署到Spark Streaming应用程序的问题,其中存在具有不同版本的全等JAR,这些JAR导致引发运行时异常的火花。有问题的图书馆是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的任何引用。但是,这不起作用。它匹配我的项目中的多个类,并导致它们从超级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$1.class
  class name: ***/SparkBaseJobRunner$$anonfun$1.class

我也尝试过使用:

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

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

我不确定我是否完全理解了阴影对我的构建过程的影响。

如何在项目中对com.typesafe.config的引用进行着色,这样当我在运行时调用库时,Spark会加载我的着色库并避免版本控制引起的冲突?

我正在运行sbt-assembly v0.14.1

1 个答案:

答案 0 :(得分:12)

结果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
)

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

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

修改

我写了一篇blog post来描述这个问题以及为有兴趣进行更深入解释的人提供的过程。