在Maven中创建依赖关系组以供重用 - 包括“提供的”依赖关系

时间:2011-05-26 04:32:56

标签: java maven-2 dependencies

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

我在pom最佳做法上阅读了this article。我喜欢将相关依赖项组合到poms中然后根据需要将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部分,但之后我将不得不重新声明每个子项目中的每个依赖项(没有版本)。

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

3 个答案:

答案 0 :(得分:6)

对您的问题的简短回答是,您应该只在本地包含代码要求编译的“提供的”依赖项,而不是在父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中维护得很糟糕。

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

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

答案 1 :(得分:3)

我的结论是,Maven不是为这种用例而设计的。我最终得到了一个父pom.xml,其中我使用的所有库都添加到了<dependencyManagement>部分。我创建的任何新项目/模块都会从父pom.xml继承pom.xml,并将所需的每个依赖项添加到自己的<dependencies>部分,减去版本。这个方案允许我管理我使用的库的版本以及他们在一个地方需要的存储库声明。另一个优点(与尝试以某种方式创建依赖包)相比,这对添加到子poms的库提供了更细粒度的控制 - 只添加了实际需要的依赖项。

答案 2 :(得分:0)

提供范围的依赖关系确实是从 POM继承的,但不是从POM定义为依赖关系而且我认为是Maven的弱点。

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

相关问题