sbt-assembly:生成一个最小的JAR文件

时间:2016-11-30 21:55:48

标签: scala jar sbt sbt-assembly

我一直在使用sbt-assembly为我的scala项目生成独立的JAR文件。但是,我想减小我的JAR文件的大小(目前大约150MB,并且那里有很好的改进空间)。

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

jar tf <JAR file>

这表明生成的JAR文件中有很多类没有在项目中使用。我相信这些课程是第三方JAR的一部分。

问题

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

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

提前致谢。

2 个答案:

答案 0 :(得分:2)

不容易来说明项目中使用的是什么,不是什么。如果在项目中包含依赖项,则可能会引入其他一些依赖项。这些子项依赖项可能还需要它们自己的依赖项等等。

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

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

此处也有反例:Scalatest不会发送pegdown来生成html测试报告,因为您通常不需要它。但是,如果您尝试使用-h标志来生成html,则可能需要它。

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

有两种排除依赖关系的方法:

  1. 使用exclude排除传递依赖项。请参阅文档here
  2. 不要使用顶级依赖项,并根据需要手动添加其子依赖项。
  3. 好的,另一个不太有趣的选择:使用provided并确保库被复制到目标环境并且在classpath上。如果您有许多使用相同库的罐子,这有助于分享这些库。
  4. 您可以使用此插件可视化您的依赖关系树:https://github.com/jrudolph/sbt-dependency-graph。在尝试找出您正在使用的内容以及可以删除的内容时,它非常有用。人们建议使用tattletaleloosejar之类的工具,但我还没有尝试过。如果有人有经验,请分享。

答案 1 :(得分:0)

可能需要关注的是 treeshakers

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

http://proguard.sourceforge.net/