【问题标题】:Differences between dependencyManagement and dependencies in maven for "provided" scopemaven中“提供”范围的dependencyManagement和依赖项之间的差异
【发布时间】: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 中的 &lt;dependency&gt;

如果必须使用&lt;exclusion&gt;,我必须在所有依赖项中明确给出它。所以,我决定走&lt;scope&gt;provided&lt;/scope&gt;的方式。

我的问题基于 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>

问题:

如果我在没有&lt;dependencyManagement&gt; 的子 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 中的&lt;dependencyManagement&gt; 标记中提到相同,provided 范围被应用。

为什么version 受到影响,但scope&lt;dependency&gt; 标记内给出,而scope(对于这种用例)我必须选择&lt;dependencyManagement&gt;

说如果允许这样做,会导致我们遇到什么问题?

编辑:

i) &lt;scope&gt;provided&lt;dependencyManagement&gt;/&lt;dependencies&gt;/&lt;dependency&gt; 在子 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) &lt;scope&gt;provided 直接在子 POM 中使用 &lt;dependencies&gt;/&lt;dependency&gt; 周围没有 &lt;dependencyManagement&gt;

虽然省略了较长的路径,但它并没有说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) 它被称为&lt;exclusion&gt; 而不是&lt;exclude&gt;。 2)也许这是由于Dependency mediation:“您始终可以通过在项目的 POM 中显式声明它来保证版本。请注意,如果两个依赖版本在依赖树中处于相同深度,[... ] 从 Maven 2.0.9 开始,重要的是声明中的顺序:第一个声明获胜。"
  • 问题与解决版本冲突无关。这是关于范围冲突。为什么它不能像使用&lt;dependency&gt; 那样解析范围?说在最后一个 sn-p 的版本为1.4.6&lt;scope&gt;provided&lt;/scope&gt;,我将版本替换为1.8,保留相同的scope,rtds-client 作为子 pom 中其他依赖项的传递依赖项,被切换到版本1.8(解决了版本冲突),但它没有切换到provided(它仍然在compile)!它接受了明确声明的版本,但为什么不接受范围?
  • 可能造成混淆但可能有用的潜在不必要信息:我不直接在我的项目中使用 rtds-client 的类。所以我不必在&lt;dependency&gt; 中明确声明它只是为了使其成为provided(如果它确实有效)(看起来像在&lt;dependency&gt; 中明确提及依赖项的目的仅针对版本及其对依赖项的意义其类必须直接在我们的项目中使用)尽管这听起来对我来说是一个很好的解决方案。
  • [续] 所以最好在子 pom 或父 pom 中提及 provided 内的 &lt;dependencyManagement&gt; 以传播此标签内的所有内容,如果它们被用于层次结构。但是假设我在我的项目中使用 rtds-client 类,这种方法听起来是一个非常有效的解决方案。
  • 依赖中介不仅仅与版本有关。这只是一个例子。它涉及整个依赖项及其声明。 “因与 1.8 冲突而省略”是因为这种调解,因为文档在上一句中也说:“目前,Maven 2.0 仅支持使用“最近定义”,这意味着它将使用依赖项树中与您的项目最接近的依赖项的版本。"。如果没有完整的 POM,很难说这种行为(provided 中的 &lt;depMgmt&gt;&lt;dep&gt;)是否是有意的,因此是合乎逻辑的还是可能是一个错误。

标签: maven maven-3 pom.xml parent-pom transitive-dependency


【解决方案1】:

我无法理解您在&lt;dependencyManagement&gt;&lt;dependency 中的&lt;scope&gt;provided

如果我声明一个子 POM,而父 POM 中没有任何 dependency[Management],例如:

<project ...>
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>igb.so</groupId>
        <artifactId>SO-44987444-parent</artifactId>
        <relativePath>../SO-44987444-parent</relativePath>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <artifactId>SO-44987444-child</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-text</artifactId>
            <version>1.1</version>
            <!--  has a dependency of org.apache.commons:commons-lang3:jar:3.5:compile -->
        </dependency>
    </dependencies>

</project>

dependency:tree 看起来像:

[INFO] ------------------------------------------------------------------------
[INFO] Building SO-44987444-child 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ SO-44987444-child ---
[INFO] igb.so:SO-44987444-child:jar:0.0.1-SNAPSHOT
[INFO] \- org.apache.commons:commons-text:jar:1.1:compile
[INFO]    \- org.apache.commons:commons-lang3:jar:3.5:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

如果我将commons-lang3 添加为与&lt;scope&gt;provided 的直接依赖关系:

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.5</version>
            <scope>provided</scope>
        </dependency>

dependency:tree 看起来像:

[INFO] ------------------------------------------------------------------------
[INFO] Building SO-44987444-child 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ SO-44987444-child ---
[INFO] igb.so:SO-44987444-child:jar:0.0.1-SNAPSHOT
[INFO] +- org.apache.commons:commons-text:jar:1.1:compile
[INFO] \- org.apache.commons:commons-lang3:jar:3.5:provided
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

即使我添加到父 POM:

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>3.5</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

dependency:tree 结果没有任何不同。

【讨论】:

  • 没错。这就是我期望它的行为方式。但是我的依赖树结果与来自 eclipse(3.3.3 嵌入式)[也来自 maven 命令行(3.5.0)] 的 dependency:tree 和 Eclipse Mars.2 版本(4.5.2)的 UI Dependency Hierarchy 不匹配模式和你一样。
  • @user104309 正如我已经在对您的问题的评论中提到的那样,如果没有完整的 POM,很难判断出什么问题。如果您添加它们(父母加一个孩子),我可以进一步研究。
  • POM 太大。我在 POM 中添加了更多信息。最后,看起来所有的混乱都是因为 Eclipse 中的 UI Dependency Hierarchy 表示依赖关系树的方式(在场景 2 的省略号上没有显示 provided 标记,而在场景 1 前导显示 provided 标记我认为在场景 2 中 rtds-client 将在构建期间打包,因为provided 范围不适用于那些省略的传递依赖项)? scope not updated to compile 是什么意思? maven 试图通过该信息传达什么信息?
猜你喜欢
  • 2018-05-19
  • 2018-07-30
  • 2016-05-28
  • 2021-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-01
相关资源
最近更新 更多