【发布时间】:2017-12-12 17:39:32
【问题描述】:
我提到了这个帖子differences between dependencymanagement and dependencies in maven,但这个问题很具体。
父 POM:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.company.rtdp.rtds</groupId>
<artifactId>rtds-client</artifactId>
<version>${rtdp.rtds-client.version}</version>
<!-- SCENARIO 1 : Either give scope here in parent POM -->
<!-- <scope>provided</scope> -->
</dependency>
</dependencies>
</dependencyManagement>
<rtdp.rtds-client.version>1.4.6</rtdp.rtds-client.version>
子 POM:
<dependencies>
<!-- SCENARIO 2
<dependency>
<groupId>com.company.rtdp.rtds</groupId>
<artifactId>realtimedataserv-client</artifactId>
<version>1.4.6</version>
<scope>provided</scope>
</dependency>
-->
<dependency>
<groupId>com.company.idi</groupId>
<artifactId>idi-persistence</artifactId>
<version>3.3</version>
<!-- has a dependency of com.company.rtdp.rtds:rtds-client:jar:1.4.6:compile -->
</dependency>
</dependencies>
<!-- SCENARIO 1: OR give scope here in child POM
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.company.rtdp.rtds</groupId>
<artifactId>rtds-client</artifactId>
<version>1.4.6</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>
-->
rtds-client 是许多工件的传递依赖,其中idi-persistence 就是其中之一。我想在所有传递依赖项中排除 1.4.6,因为我将明确包含一个不同的工件 rtds-framework-client(不同的工件名称),它向后兼容 1.4.6 和子 POM 中的 <dependency>。
如果必须使用<exclusion>,我必须在所有依赖项中明确给出它。所以,我决定走<scope>provided</scope>的方式。
我的问题基于 Maven 的已知信息:
如果我在子 POM 中包含以下内容(版本高于 1.4.6,则所有传递依赖项中的 rtds-client 都会转移到 1.8。我可以从 Eclipse 的 'Dependency Hierarchy' 看到这一点,上面写着 'omitted for conflict with 1.8' [compile]) 这意味着它考虑/覆盖子 POM 中指定的版本(idi-persistence 现在获得 1.8)。
<dependency>
<groupId>com.company.rtdp.rtds</groupId>
<artifactId>rtds-client</artifactId>
<version>1.8</version>
</dependency>
问题:
如果我在没有<dependencyManagement> 的子 POM 中包含以下内容:
<dependency>
<groupId>com.company.rtdp.rtds</groupId>
<artifactId>rtds-client</artifactId>
<version>1.4.6</version>
<scope>provided<scope>
</dependency>
作为传递依赖的rtds-client 没有一个考虑provided 范围,而我在父或子POM 中的<dependencyManagement> 标记中提到相同,provided 范围被应用。
为什么version 受到影响,但scope 在<dependency> 标记内给出,而scope(对于这种用例)我必须选择<dependencyManagement>?
说如果允许这样做,会导致我们遇到什么问题?
编辑:
i) <scope>provided 和 <dependencyManagement>/<dependencies>/<dependency> 在子 POM 或父 POM 中:
虽然省略了较长的路径,但这里显示的是[provided]。
[INFO] +- com.company.idi:idi-persistence:jar:3.3:compile
[INFO] | +- com.company.rtdp.rtds:realtimedataserv-client:jar:1.4.6:provided
ii) <scope>provided 直接在子 POM 中使用 <dependencies>/<dependency> 周围没有 <dependencyManagement> :
虽然省略了较长的路径,但它并没有说provided,而只是compile。
[INFO] --- maven-dependency-plugin:2.3:tree (default-cli) @ read-rest-service ---
[INFO] +- com.company.rtdp.rtds:realtimedataserv-client:jar:1.4.6:provided (scope not updated to compile)
【问题讨论】:
-
1) 它被称为
<exclusion>而不是<exclude>。 2)也许这是由于Dependency mediation:“您始终可以通过在项目的 POM 中显式声明它来保证版本。请注意,如果两个依赖版本在依赖树中处于相同深度,[... ] 从 Maven 2.0.9 开始,重要的是声明中的顺序:第一个声明获胜。" -
问题与解决版本冲突无关。这是关于范围冲突。为什么它不能像使用
<dependency>那样解析范围?说在最后一个 sn-p 的版本为1.4.6<scope>provided</scope>,我将版本替换为1.8,保留相同的scope,rtds-client 作为子 pom 中其他依赖项的传递依赖项,被切换到版本1.8(解决了版本冲突),但它没有切换到provided(它仍然在compile)!它接受了明确声明的版本,但为什么不接受范围? -
可能造成混淆但可能有用的潜在不必要信息:我不直接在我的项目中使用 rtds-client 的类。所以我不必在
<dependency>中明确声明它只是为了使其成为provided(如果它确实有效)(看起来像在<dependency>中明确提及依赖项的目的仅针对版本及其对依赖项的意义其类必须直接在我们的项目中使用)尽管这听起来对我来说是一个很好的解决方案。 -
[续] 所以最好在子 pom 或父 pom 中提及
provided内的<dependencyManagement>以传播此标签内的所有内容,如果它们被用于层次结构。但是假设我在我的项目中使用 rtds-client 类,这种方法听起来是一个非常有效的解决方案。 -
依赖中介不仅仅与版本有关。这只是一个例子。它涉及整个依赖项及其声明。 “因与 1.8 冲突而省略”是因为这种调解,因为文档在上一句中也说:“目前,Maven 2.0 仅支持使用“最近定义”,这意味着它将使用依赖项树中与您的项目最接近的依赖项的版本。"。如果没有完整的 POM,很难说这种行为(
provided中的<depMgmt>与<dep>)是否是有意的,因此是合乎逻辑的还是可能是一个错误。
标签: maven maven-3 pom.xml parent-pom transitive-dependency