【问题标题】:How maven dependency exclusion works for this scenariosmaven 依赖排除如何在这种情况下工作
【发布时间】:2021-08-13 18:29:42
【问题描述】:

我很难理解 maven 依赖管理以及依赖排除的工作原理。我所知道的是,当 A 类的某个对象向另一个 B 类的另一个对象发送消息(调用方法)时,A 类与 B 类耦合(A 类需要 B 类存在)。

我在项目中使用 Maven,并且在 pom 中有这个依赖:

<dependencies>
    <dependency>
        <groupId>org.libraries</groupId>
        <artifactId>library-A</artifactId>
    </dependency>
</dependencies>

现在假设class A 来自library-A,它取决于library-B 中的class B,但我在我的项目中不使用class A(我使用另一类library-A 不耦合到任何library-B 的类)。 即使没有在我的项目中使用,Maven 也会下载并安装到本地存储库中?

现在假设一个不同的场景,我在我的项目中使用 library-A 中的 class A,这取决于 library Bclass-B,但我在 pom 中排除了 library-B 的依赖关系:

<dependencies>
    <dependency>
        <groupId>org.libraries</groupId>
        <artifactId>library-A</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.libraries</groupId>
                <artifactId>library-B</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

由于我在 pom 中没有任何其他依赖于 library-B 的依赖项,项目是否会编译但在类加载期间程序的执行会失败,因为找不到该类?

现在假设我将在我的项目中使用来自library-Aclass A,这取决于library Bclass-B,但我在pom 中排除了library-B 的依赖关系,尽管我有@ 的依赖关系987654341@ 取决于(如library-Alibrary-B

<dependencies>
    <dependency>
        <groupId>org.libraries</groupId>
        <artifactId>library-A</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.libraries</groupId>
                <artifactId>library-B</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.libraries</groupId>
        <artifactId>library-C</artifactId>
    </dependency>
</dependencies>

现在虽然我排除了library-Alibrary-B 的传递依赖,** 项目是否可以正常编译和执行,library-A 中的class A 将使用library-B,因为传递依赖library-C 具有在library-B 上(假设这个library-B 版本与library-A 兼容)?

最后一个问题是,当我排除 library-Alibrary-B 的依赖并使用 dependency:tree -Dverbose 查看依赖关系图时,它不会显示在图形中 library-A 具有 library-B 依赖关系,尽管它可以真的使用传递性的依赖,因为另一个依赖我错了吗?如果我没记错的话,我怎么知道library-A 是否真的使用了那个依赖?

【问题讨论】:

  • 您的问题有很多要解开的内容。一般来说,排除您确定自己或其他依赖项都未使用的依赖项不应在运行时或编译时产生任何问题(库是在您的排除存在的情况下编译的,而您自己没有使用该库,所以它当然会编译)。如果您使用库 A 的一部分然后将其排除,它将无法编译(当然)。关于 Maven 下载库:如果您在 pom 中添加依赖项,Maven 将包含它,因为这就是您指定的内容:)
  • 如果使用库-A 的一部分,而库-A 又使用库-B 和库-B 被排除在该依赖项中,但库-C 也使用库-B,它将编译并且库-A 将使用library-B 虽然因为它来自另一个依赖项而被排除在外?
  • 排除依赖项不会不会阻止其他依赖项尝试使用该依赖项中的类,除非这些库的实现方式是您排除的依赖项对它们来说是可选的(这个有可能)。如果您使用内部使用库 B 的库 A 并且排除库 B,您将遇到运行时问题。如果库 A 的 API 泄​​漏库 Bs 类,您可能会遇到编译问题。也许最好解释一下你想要达到的目标,而不是在这个非常理论的层面上讨论
  • 我知道排除一个依赖项不会阻止其他依赖项使用它。但是,如果库-A 正在使用库-B 并排除它,但我还使用库-C,它也使用库-B,库-A 是否会编译并使用库-B(因为库-B 可用导致库-C依赖)?我正在尝试修复依赖关系问题,并且需要知道何时真正使用依赖关系或在排除时不使用依赖关系..
  • 从库 A 中排除传递依赖不会阻止库 C 在依赖树中“引入”相​​同的依赖。如果库 C 提供其传递依赖项 B,那么库 A 将工作 - 但前提是版本匹配 / 兼容。

标签: java maven dependency-management dependency-exclusion


【解决方案1】:

让我试着更一般地回答你的问题:

  1. Maven 不会分析您使用(或不使用)哪些类。它只是确定传递依赖的树。

  2. 最后,Maven 创建了一个类路径。类路径是平坦的,给定依赖项来自哪一侧并不重要。

  3. 缺少传递依赖可能会导致编译时和运行时出现问题。前面的问题很少见,但如果例如传递依赖被用作超类或在接口中可能会发生这种情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-25
    • 1970-01-01
    • 2020-11-21
    • 2018-06-16
    • 2017-06-21
    • 2018-01-19
    相关资源
    最近更新 更多