【问题标题】:sbt-assembly: Generate a minimal JAR filesbt-assembly:生成最小的 JAR 文件
【发布时间】:2017-04-15 09:37:07
【问题描述】:

我一直在使用 sbt-assembly 为我的 scala 项目生成独立的 JAR 文件。不过,我想减小我的 JAR 文件的大小(目前约为 150MB,而且肯定有改进的余地)。

我使用以下命令列出了生成的 JAR 文件的内容:

jar tf <JAR file>

这表明生成的 JAR 文件中有很多类在项目中没有使用。我相信这些类会被包含在第三方 JAR 中。

问题

(a) 是否有一个选项可用于指示 sbt-assembly 生成一个最小 JAR 文件,其中不包含我的项目中未使用的第三方类?

(b) 我可以使用 AssemblyStrategy 手动指定需要排除的文件。这是一个合理的策略吗?我有点担心使用这种方法,JAR 文件最终可能会引发意外的 ClassNotFound 异常。

提前致谢。

【问题讨论】:

    标签: scala jar sbt sbt-assembly


    【解决方案1】:

    不容易说出您的项目中使用了什么,没有使用什么。如果您在项目中包含一个依赖项,它可能会引入其他一些依赖项。这些子依赖项可能还需要它们自己的依赖项,依此类推。

    默认情况下,如果您在项目中包含一些依赖项,您打算使用它。依赖的作者通常做同样的事情。因此,通常你可以扔掉的东西不多,它的存在是有原因的。有几种情况不是这样的:

    • 依赖关系作者包含仅在某些设置中使用的其他依赖关系,并且不适用于您的项目
    • 当您实际上只需要其中一个库/功能时,您正在使用超级依赖项。

    也有反例:Scalatest 不提供pegdown 用于生成 html 测试报告,因为您通常不需要它。但如果您尝试使用-h 标志生成html,则可能需要它。

    想象一下使用 Apache Tika 进行 pdf 解析的情况。它包装 PDFBox 进行解析。在这种情况下,您不需要 all other libraries 的膨胀来解析 MS 文档。最好的办法是不要通过 sbt excludesbt-assembly 规则手动排除文件,因为存在您弄错的风险并获得运行时类加载异常。相反,您需要直接使用正确的依赖项,例如 PDFBox。不幸的是,在很多情况下,这需要大量的手动工作来找出您需要的所有依赖项,所以这是您的选择:简单而胖的 JAR,或者痛苦而精简。

    排除依赖有两种方式:

    1. exclude 排除传递依赖。请参阅文档here
    2. 不要使用顶级依赖项并根据需要手动添加其子依赖项。
    3. 好的,还有一个不那么有趣的选项:使用provided 并确保将库复制到您的目标环境并位于类路径中。如果您有许多 jar 使用相同的库,这有助于共享这些库。

    您可以使用此插件可视化您的依赖关系树:https://github.com/jrudolph/sbt-dependency-graph。在尝试弄清楚您正在使用什么以及可以删除什么时,这非常有用。人们建议使用一些工具,例如tattletaleloosejar,但我没有尝试过。如果有人有这方面的经验,请分享。

    【讨论】:

    • 谢谢。我现在决定使用基于provided 的方法。我还将检查有助于可视化依赖关系图的工具。
    【解决方案2】:

    可能要查看的是 treeshakers

    对于 Java,有以下内容(我没有尝试/使用过):

    http://proguard.sourceforge.net/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-17
      • 1970-01-01
      • 2013-09-15
      • 1970-01-01
      • 2021-12-27
      • 2013-01-20
      • 1970-01-01
      相关资源
      最近更新 更多