【问题标题】:Create dependency groups in Maven for reuse - including 'provided' dependencies在 Maven 中创建依赖组以供重用 - 包括“提供的”依赖项
【发布时间】:2011-09-02 06:51:43
【问题描述】:

我是 Maven 新手,正在建立我的第一个 Maven 项目。我还以一些 pom 的形式创建了一些 maven 资产,这些资产也可以从任何未来的项目中继承或用作依赖项。我想将依赖项组合在一起,并能够根据需要有选择地将它们添加到项目中。

我阅读了关于 pom 最佳实践的 this article。我喜欢将相关的依赖项组合到 pom 中,然后根据需要将 pom 作为依赖项添加到项目中的想法。这种方法非常适合编译作用域依赖项。但是,对于提供的作用域,它会失败,因为作为传递依赖,它们会被省略。

这是我的意思的一个例子:假设我将我的项目的 Web 依赖项组合到一个 web-deps pom.xml 中。其中包括 compile 范围的 Spring 框架依赖项以及 provided 范围的 javaee 之一:

<modelVersion>4.0.0</modelVersion>
<groupId>com.xyz</groupId>
<artifactId>mvn-web-deps</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
        <groupId>javaee</groupId>
        <artifactId>javaee-api</artifactId>
        <version>${javaee.version}</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

然后我将此 pom 作为依赖项添加到另一个项目中:

<modelVersion>4.0.0</modelVersion>
<groupId>com.xyz</groupId>
<artifactId>project-a</artifactId>
<version>0.0.1-SNAPSHOT</version>

<dependency>
    <groupId>com.xyz</groupId>
    <artifactId>mvn-web-deps</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <type>pom</type>
</dependency>

mvn-web-deps 中的依赖关系现在变为传递。由于上面的依赖引用是compile 作用域的,所以provided 传递依赖被省略了。

我想避免将它们添加到父级的dependency 部分,因为只能有一个父级,并且项目可能只需要其中一些依赖组,而不是全部。我或许可以将它们添加到 dependencyManagement 部分,但随后我将不得不在每个子项目中重新声明每个依赖项(无版本)。

在避免上述问题的同时,对依赖项进行分组的正确/更好的方法是什么?

【问题讨论】:

  • 这对即使是编译范围也不起作用

标签: java maven-2 dependencies


【解决方案1】:

对您的问题的简短回答是,您应该只在代码需要编译的本地包含“提供的”依赖项,而不是在父 pom.xml 或其他结构中。表明你在全局 pom.xml 中有一个“提供”的依赖对 maven 来说是没有意义的,因为它不需要在这样的 pom.xml 中编译。

这里是长答案:

当我开始使用 Maven 时,我有相同的想法,即尝试将工件和依赖项分组到 pom.xml 模块中,希望它们在将来有用。现在,我有了更多的经验,我明白这完全是浪费时间。对我来说,这是一种过度设计。

我学会了将我的大项目拆分为单独的模块,每个模块都在自己的 subversion 存储库中。我在 pom.xml 中包含每个本地模块所需的依赖项。我在编码时和必要时(即在测试和稳定时)发布每个模块的版本化标签。

我通过使用自己的 pom.xml 创建一个单独的 maven 项目并将我的模块作为依赖项导入来构建我的大型项目。发布时,我会不时更新依赖项中的模块版本。然后,在编译/发布大项目时,我让 maven 完成它必须拉出的任何内容的工作。

Maven 允许在 pom.xmls 之间进行各种复杂的结构和层次结构,但恕我直言,这个特性会造成不必要的混乱和复杂性。到目前为止,它还没有证明对我有真正的好处。一开始,我希望编译一个 pom.xml 能够以级联方式正确编译其余部分。我确实得到了一些结果,但是在所有全局 pom.xml 中维护的都是一团糟。

分别发布我的模块的工件并在这些版本上构建我的项目为我节省了很多时间,我只能推荐它。总的来说,我需要维护的 pom.xml 更少,而且它们也不那么复杂。对于相同的最终结果...

所以,如果你构建 global/structural pom.xml 的唯一原因是希望节省时间,我建议放弃这个想法......在单独的项目中单独代码,发布然后全局编译。

【讨论】:

  • 感谢您的回复。也许我没有很清楚地说明我使用这种分组依赖项的动机。我也将我的项目分解为模块。我希望通过将相关依赖项组合在一起来实现的是能够在一个地方管理它们并通过简单的引用跨项目重用它们。续……
  • 我有一套或多或少固定的技术,用于开发 Web 项目,例如,在我的组织中。所以所有的 web 项目至少有一些共同的依赖集,这是必须的。我想将它们维护在一个地方,以便本地化存储库、组 ID、工件 ID 和版本号的知识,并且每个开始新 Web 项目的开发人员都不必担心它们,并且可以以某种方式引用这些依赖项.
【解决方案2】:

我的结论是 Maven 不是为这种用例设计的。我最终有了一个父 pom.xml,我使用的所有库都添加到了它的 &lt;dependencyManagement&gt; 部分。我创建的任何新项目/模块都有它们的pom.xml 继承自父pom.xml 并将它们需要的每个依赖项添加到它们自己的&lt;dependencies&gt; 部分,减去版本。这个方案允许我在一个地方管理我使用的库的版本和他们需要的存储库声明。另一个优点(相对于尝试以某种方式创建依赖包)是,这可以对添加到子 pom 的库进行更细粒度的控制 - 仅添加实际需要的依赖项。

【讨论】:

    【解决方案3】:

    提供范围的依赖确实是从 parent POM 继承的,但不是从定义为 dependencies 的 POM 继承的,我认为这是 Maven 的弱点。

    鉴于 Maven 在添加模块作为跨模块层次结构的依赖项方面也存在困难,我不能说 Maven 是管理多模块项目的复杂 工具。 Maven 需要一个严格的单根层次结构,它只适用于最简单的项目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-23
      • 2011-02-27
      • 1970-01-01
      • 1970-01-01
      • 2017-01-01
      • 2023-03-24
      • 2014-11-06
      • 2016-10-16
      相关资源
      最近更新 更多