2016-11-30 16 views
3

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

我用下面的命令列出的出品的JAR文件的内容:

jar tf <JAR file> 

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

问题

(a)是没有办法,我可以用它来指导SBT-组件产生最小的JAR文件不包括未在我的项目中使用的第三方类的选项? (b)我可以使用AssemblyStrategy手动指定需要排除哪些文件。这是一个合理的策略吗?我有点担心用这种方法JAR文件可能会抛出意想不到的ClassNotFound异常。

在此先感谢。

回答

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并确保库复制到目标环境并位于类路径中。如果你有很多使用相同库的罐子,这有助于分享这些罐子。

你可以用这个插件可视化你的依赖关系树:https://github.com/jrudolph/sbt-dependency-graph。当试图找出你正在使用的东西以及你可以删除的东西时,它非常有用。有人建议使用tattletaleloosejar等工具,但我没有尝试过。如果有人有与这些经验,请分享。

+0

谢谢。我决定现在使用“提供”的方法。我还会检出帮助可视化依赖关系图的工具。 – jithinpt