Maven 是否有依赖工件的“仅限编译器”范围

问题描述 投票:0回答:2

我意识到这更多的是语义探索而不是功能探索。

我有三种类型的编译范围依赖项:

  1. 仅编译范围,不在运行时使用。 GWT 客户端开发、MVP4G、RestyGWT、源保留注释处理器。我使用 REST,所以不需要 GWT 服务器端。

  2. 提供 - 编译所需的 Hibernate jar,但由 JBoss 提供。

  3. 编译+运行时jar。

对于情况 2,我们可以使用提供的范围。情况 3,我们将使用编译范围。

但是对于情况 1,我使用提供的范围,即使 JBoss 根本不提供这些文件。运行时也不需要它们。

无论如何,您不认为 Maven 应该为除了编译时之外并不真正需要工件的范围提供“提供”的同义词吗?也许,应该有一个“仅编译”范围?

java maven semantics
2个回答
15
投票

如果依赖项仅用于构建,例如注释处理器,则它应该是 Maven

<plugin>
,或其
<dependency>

否则,如果它在编译类路径中,则需要在运行时链接生成的类文件。那么,有两种情况:

  1. 总是需要加载该类
    1. 课程应作为申请的一部分发送:
      <scope>compile</scope>
    2. 该类应由运行时环境提供:
      <scope>provided</scope>
  2. 有时是必要的(因为该类仅在特定情况下才会加载):
    <optional>true</optional>

唯一没有涵盖的选项是编译 Java 程序,并且永远不要在 JVM 中运行它。这是一个非常晦涩的用例,我不能责怪 Maven 的设计者没有包含一个范围只是为了表达这种区别 - 特别是因为它与 Maven 的核心职责(构建软件)无关。


9
投票

如果 jar 不是真正的“运行时”依赖项(仅用于构建)但不是最终工件,您可以通过各种方式排除它们:

  1. 程序集描述符中的排除
  2. jar(或 war、ear 等等)插件配置中的排除
  3. Shade 插件最小化 jar 目标

我同意传送不必要的类很烦人(我在生产部署中见过 junit 和 testng jar - brrrr ...),但对于所有实际目的来说,这是一个相当小的问题。

如果您存在依赖项冲突(即交付库或框架的“所有部门”版本),那是一个不同的故事,但听起来不像您在这里面临的情况。

© www.soinside.com 2019 - 2024. All rights reserved.