【问题标题】:Selectively include dependencies in JAR在 JAR 中选择性地包含依赖项
【发布时间】:2011-11-14 01:59:35
【问题描述】:

我有一个用 Scala 编写的库,它使用 Bouncy Castle 并且有一大堆依赖项。当我滚动一个罐子时,我可以滚动一个包含所有依赖项(包括 scala)的“胖”罐子,它重约 19 MB,或者我可以滚动一个瘦罐子,它没有t 有依赖关系,但只有几百 KB。

问题是我需要在我的库中包含 Bouncy Castle 类/jar,因为如果它在运行时不在类路径中,则会引发各种异常。

所以,我认为理想的情况是,如果有某种方法可以让 Maven 或 SBT 在获得的 jar 中包含 some 但不包含 all 依赖项滚动。在编译时需要一些依赖项,但在运行时不需要,例如 Scala 标准库。有什么方法可以实现吗?

谢谢!

【问题讨论】:

    标签: scala maven jar packaging sbt


    【解决方案1】:

    覆盖maven...

    因为您在 maven pom 中声明您的项目依赖于 bouncy castle,所以使用 maven 依赖于您的库的任何人默认情况下都会将 bouncy castle 作为传递依赖项拉入。

    您应该为您的依赖项设置适当的 范围,例如编译在编译和运行时需要的东西,测试仅在测试中需要的依赖项,并为您希望由环境提供的东西提供。

    您的库的依赖项在构建时是否被打包到依赖项目中是一个问题,即项目如何配置以及设置范围将影响默认行为。

    例如,jar type packaging 默认情况下不包括依赖项,而 war 将包括那些在编译范围内的(但不包括测试或提供)。这里的设计目标是让打包插件以最常用的方式运行,而无需配置,但当然,如果需要,maven 中的打包插件可以配置为具有不同的行为。进行打包的插件本身在 apache maven 站点上有很好的记录。

    如果你的库的用户不太可能使用 maven 来构建他们的项目,一个选项是使用 shade 插件,它允许你生成一个“uber-jar”,其中包含你想要的所有依赖项。您可以配置特定的包含或排除。

    这可能是一种有问题的交付方式,例如,当您的库包含的依赖项与使用它的项目的直接依赖项发生冲突时,即它们使用您使用的相同库的不同版本。

    但是,如果可以的话,最好将其留给 maven 来管理,以便使用您的库的项目可以决定他们是否需要您的依赖项或指定特定版本,从而为他们提供更大的灵活性。这是惯用的方法。

    有关 maven 中的依赖项和范围的更多信息,请参阅 Sonatype 发布的reference guide

    【讨论】:

      【解决方案2】:

      我会尝试来自 https://github.com/nuttycom/sbt-proguard-plugin 的 sbt proguard 插件。它应该能够清除不使用的类。

      【讨论】:

      • +1 proguardassembly xml-hell 相比看起来非常好。
      • 最重要的是它会减少库的大小而不是数量; scala 库本身就超过 8 兆
      • 有没有办法告诉 pro guard 不包括 scala-libs?
      • 不确定你要做什么。如果您编写了 scala 应用程序,您至少需要 scala-libs 的某些部分
      【解决方案3】:

      我不是 scala 人,但我玩过用 Java + Maven 组装东西。

      您是否尝试过为程序集插件创建自己的程序集描述符? https://maven.apache.org/plugins/maven-assembly-plugin/assembly.html

      您可以复制/粘贴 jar-with-dependencies 描述符,然后将一些排除项添加到您的 。我不是 Maven 专家,但您应该能够对其进行配置,以便不同的配置文件启动不同的程序集构建。

      编辑:Ack,没有看到我的 HTML 被隐藏了

      【讨论】:

        【解决方案4】:

        如果明确定义应该添加哪些依赖项(一个工件级别,即单个 JAR)就足够了,您可以定义一个 程序集(如果是单个项目)或一个额外的组装项目(如果是多模块项目)。程序集描述符可以显式地从依赖项中排除/包含工件。

        Here 是关于这个主题的一些很好的文档(第 8.5.4 节),here 是官方文档。

        请注意,您可以通过在dependecySets 中使用通配符 来包含属于一个组的所有工件,例如hibernate:*:jar 将包括属于休眠组的所有 JAR 文件。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-01-13
          • 1970-01-01
          • 2023-03-30
          • 2015-12-27
          • 1970-01-01
          • 2010-12-16
          • 2016-06-04
          相关资源
          最近更新 更多