如何使用已标记为已提供的项目的依赖项?

How can I use dependencies of a project that's been marked as provided?

我有以下简化的场景:

projectX  ---> projectA ---> projectB

其中 ---> 表示 "depends on"。

ProjectB真的很简单。它没有声明任何依赖项。事实上,唯一相关的部分是:

<packaging>jar</packaging>

在项目A的pom.xml中我已经声明了对项目B的依赖:

<packaging>jar</packaging>
<dependencies>
    <dependency>
        <groupId>com.mycompany</groupId>
        <artifactId>projectB</artifactId>
        <version>1.0.0</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

并且在 projectX 的 pom.xml 中我有:

<packaging>war</packaging>
<dependencies>
    <dependency>
        <groupId>com.mycompany</groupId>
        <artifactId>projectA</artifactId>
        <version>1.0.0</version>
        <scope>compile</scope>
    </dependency>
</dependencies>

问题是 projectX 需要使用 projectB 中定义的组件(类 等)。如果我将 projectA 中的范围更改为对 projectB 使用 compile,则一切正常,但是在 projectX 中生成 war 时将包含 projectB,并且我需要从生成的 war 因为我在项目的其他部分提供了 projectB。

在实际场景中,我有几个像projectB这样的依赖会影响projectA,所以为了减少生成的大小war,我想按提供的方式设置它们,但是projectX无法使用这些组件在任何这些库中定义。组件示例:Spring、Hibernate 等

问题:有没有一种方法可以干净地实现这一点,而无需在很多地方重新声明依赖项?

The problem is that projectX needs to use components (classes and such) that are defined in projectB.

那么 ProjetB 应该确实是 ProjectX 的依赖项,在 provided 范围内。重新声明依赖项将改变 Maven 将其作为传递依赖项处理的方式(也就是说,您可以通过说:我希望在我的项目中使用此范围的此依赖项来覆盖其行为)。

but then projectB will be included when generating the war in projectX, and I need to have this library out of the generated war

provided 范围内重新声明它不会发生这种情况。或者,您可以将 ProjectA 中的 ProjectB 的范围更改为 compile,然后配置 maven-war-plugin to exclude them, using inclusions/exclusions.
不过,在这样做之前,您应该仔细检查为什么在语义上(或需求方面)ProjectB 在 ProjectA 中设置为 provided,以及它对其他消费者项目的影响。


更新
以上两种方法都可以满足您的需求。或者,正如评论中所建议的那样,从 运行 走向更好的治理和维护(集中化)的长远来看,进一步的选择可能更加可持续和明确:

  • 使用公共 parent pom,您可以在其中声明共享依赖项列表,即所有子项目将使用的依赖项,定义(和维护)一次。
  • 使用 dependencyManagement section in ProjectX to change how Maven dependencies mediation would handle transitive dependencies on ProjectA, without changing ProjectA or ProjectB (similar to option 1 at the top of this answer, with the difference 它只会在依赖项进入范围时应用,否则将被忽略)。同样,要集中此管理,最好在一个共同的父级(上面的选项)中这样做。