声明依赖于<dependencyManagement>部分,即使依赖项没有在任何地方使用?

Mik*_*one 19 java dependencies maven-2

我们正在使用maven 2.1.0.我有多个完全独立的模块,但仍有许多常见的依赖项.像log4J,但有些模块不需要它.我想知道在该<dependencyManagement>部分中的一个父文件中声明所有公共依赖项是否是一个好主意,还是有更好的方法来处理它?

关于的后续问题<dependencyManagement>.如果我<dependencyManagement>在父项的部分中声明Log4J 并且子项目不使用它,那么它是否会被包括在内?

Ric*_*ler 33

如果您有父项目,则可以在父pom的dependencyManagement部分中声明所有依赖项及其版本.这并不意味着所有项目都将使用所有这些依赖项,这意味着如果项目确实声明了依赖项,它将继承配置,因此它只需要声明依赖项的groupId和artifactId.您甚至可以在父级的dependencyManagement中声明子项目而不引入循环.

请注意,您也可以通过在pluginManagement部分中声明它们来实现与插件类似的操作.这意味着声明插件的任何子节点都将继承配置.

例如,如果您有4个项目,parent,core,uiutils,则可以在父项中声明所有外部依赖项和内部项目版本.然后子项目继承它们声明的任何依赖项的配置.如果所有模块都具有相同的版本,则甚至可以将这些模块声明为父级中的属性.

示例父母如下:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>name.seller.rich</groupId>
  <artifactId>parent</artifactId>
  <version>1.0.0</version>
  <packaging>pom</packaging>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>1.4</version>
      </dependency>
      <dependency>
        <groupId>name.seller.rich</groupId>
        <artifactId>ui</artifactId>
      <version>${project.version}</version>
      </dependency>
      <dependency>
        <groupId>name.seller.rich</groupId>
        <artifactId>core</artifactId>
        <version>${project.version}</version>
      </dependency>
      <dependency>
        <groupId>name.seller.rich</groupId>
        <artifactId>utils</artifactId>
        <version>${project.version}</version>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <modules>
    <module>utils</module>
    <module>core</module>
    <module>ui</module>
  </modules>
</project>
Run Code Online (Sandbox Code Playgroud)

utils,core和ui项目继承了所有相关版本.utils的:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>name.seller.rich</groupId>
  <artifactId>utils</artifactId>
  <!--note version not declared as it is inherited-->
  <parent>
    <artifactId>parent</artifactId>
    <groupId>name.seller.rich</groupId>
    <version>1.0.0</version>
  </parent>
  <dependencies>
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
    </dependency>
  </dependencies>
</project>
Run Code Online (Sandbox Code Playgroud)

核心:

<project>
<modelVersion>4.0.0</modelVersion>
<groupId>name.seller.rich</groupId>
<artifactId>core</artifactId>
<parent>
  <artifactId>parent</artifactId>
  <groupId>name.seller.rich</groupId>
  <version>1.0.0</version>
</parent>
<dependencies>
  <dependency>
    <groupId>name.seller.rich</groupId>
    <artifactId>utils</artifactId>
  </dependency>
</dependencies>
Run Code Online (Sandbox Code Playgroud)

用户界面:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>name.seller.rich</groupId>
  <artifactId>ui</artifactId>
  <parent>
    <artifactId>parent</artifactId>
    <groupId>name.seller.rich</groupId>
    <version>1.0.0</version>
  </parent>
  <dependencies>
    <dependency>
      <groupId>name.seller.rich</groupId>
      <artifactId>core</artifactId>
    </dependency>
  </dependencies>
</project>
Run Code Online (Sandbox Code Playgroud)


Cra*_*lin 16

我写了一份最佳实践清单.这是最重要的.

  • 始终使用maven-enforcer-plugin
    • 实现依赖性收敛
      • 否则,您可能依赖于两个不同的jar,这两个jar都依赖于log4j.在编译时使用哪一个取决于您不应该记住的一组规则.它们都可以(!)作为传递依赖项导出.
    • 需要插件版本(适用于所有插件,甚至是内置插件)
      • 在父pom中的pluginManagement中定义它们以定义版本
      • 否则,新版本的maven-surefire-plugin可能会破坏您的构建
  • 在父pom中使用dependencyManagement可以在所有模块中一致地使用版本
  • 定期运行mvn依赖:分析
    • 您可能会在编译时直接依赖于传递依赖关系.如果是这样,使用您需要的版本将其添加到您的pom非常重要.这与enforcer插件很好地配合.
    • 您可能声明了不使用的额外依赖项.这在100%的情况下都无法正常工作,特别是对于设计为具有可选部分的库(即,slf4j-api被正确检测到,但slf4j-log4j12失败).


Kri*_*ris 8

每个模块都应该有自己的POM,并声明自己的依赖关系.这不仅跟踪外部依赖关系,还跟踪内部依赖关系.

当您使用Maven构建项目时,它将对整个项目进行排序.因此,如果许多模块(可能全部)依赖于log4j,那么它只会被包含一次.如果您的模块依赖于不同版本的log4j,则存在一些问题,但这种方法通常可以正常工作.

它也很有用(如果有超过1-2个开发人员一起工作)来设置内部存储库(如Artifactory)并在内部使用它.这使得处理不在公共存储库中的库变得更容易(只需将其添加到您的内部存储库!)并且您还可以使用构建工具来推送您自己的代码的构建,以便其他人可以使用这些模块而无需检出代码(在大型项目中有用)