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

时间:2023-01-25 10:01:02

I have the following scenario, simplified:

我有以下场景,简化:

projectX  ---> projectA ---> projectB

Where ---> means "depends on".

--- ---表示“取决于”。

ProjectB is really simple. It doesn't declare any dependenci. In fact, the only relevant part is this:

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

<packaging>jar</packaging>

In pom.xml of projectA I have declared the dependency to projectB:

在projectA的pom.xml中,我已经向projectB声明了依赖项:

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

And in pom.xml of projectX I have:

在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>

The problem is that projectX needs to use components (classes and such) that are defined in projectB. If I change the scope in projectA to use compile for projectB, everything will work, but then projectB will be included when generating the war in projectX, and I need to have this library out of the generated war because I'm providing projectB in other part of the project.

问题是projectX需要使用projectB中定义的组件(类等)。如果我更改projectA中的范围以使用projectB的编译,一切都会工作,但是在projectX中生成war时将包含projectB,并且我需要将这个库从生成的war中取出,因为我在其他地方提供了projectB项目的一部分。

In the real scenario, I have several dependencies like projectB that affect projectA, so to reduce the size of the generated war, I would like to set them as provided, but then projectX cannot use the components defined in any of those libraries. Example of components: Spring, Hibernate, etc.

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

Question: Is there a way to achieve this in a clean way without re-declaring dependencies in lots of places?

问题:有没有办法以干净的方式实现这一点,而无需在很多地方重新声明依赖关系?

1 个解决方案

#1


6  

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

问题是projectX需要使用projectB中定义的组件(类等)。

Then ProjetB should be a dependency of ProjectX indeed, in provided scope, again. Re-declaring the dependency would change how Maven would handle it as transitive dependency (that is, you can override its behavior by saying: I want this dependency in my project with this scope).

然后ProjetB应该是ProjectX的依赖,确实在提供的范围内。重新声明依赖项将改变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

但是在projectX中生成war时将包含projectB,我需要从生成的war中获取此库

This will not happen by re-declaring it in provided scope. Alternatively, you could change the scope of ProjectB in ProjectA to compile and then configure the maven-war-plugin to exclude them, using inclusions/exclusions.
Before doing so though, you should double-check why semantically (or requirements-wise) ProjectB was set as provided in ProjectA and what would be its impact on other consumer projects.

通过在提供的范围内重新声明它不会发生这种情况。或者,您可以更改ProjectA中ProjectB的范围以进行编译,然后使用包含/排除将maven-war-plugin配置为排除它们。在此之前,您应该仔细检查为什么在ProjectA中提供的语义(或需求方式)ProjectB的设置以及它对其他消费者项目的影响。


Update
Both approaches above may suit your needs. Alternatively, as suggested in comments further options could be more sustainable and clear in the long run towards a better governance and maintenance (centralization):

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

  • Use a common parent pom where you could declare the list of shared dependencies, that is, dependencies that will be used by all children projects, defined (and maintained) once.
  • 使用公共父pom,您可以在其中声明共享依赖项列表,即所有子项目将使用的依赖项,定义(和维护)一次。

  • Use the 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 that it will only be applied whenever the dependency comes into scope and ignored otherwise). To centralize this management, again, would be better to do so in a common parent (option above).
  • 使用ProjectX中的dependencyManagement部分更改Maven依赖关系中介如何处理ProjectA上的传递依赖,而不更改ProjectA或ProjectB(类似于此答案顶部的选项1,区别在于只有在依赖关系进入时才会应用它范围,否则忽略)。再次集中管理,最好是在共同的父母(上面的选项)中这样做。

#1


6  

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

问题是projectX需要使用projectB中定义的组件(类等)。

Then ProjetB should be a dependency of ProjectX indeed, in provided scope, again. Re-declaring the dependency would change how Maven would handle it as transitive dependency (that is, you can override its behavior by saying: I want this dependency in my project with this scope).

然后ProjetB应该是ProjectX的依赖,确实在提供的范围内。重新声明依赖项将改变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

但是在projectX中生成war时将包含projectB,我需要从生成的war中获取此库

This will not happen by re-declaring it in provided scope. Alternatively, you could change the scope of ProjectB in ProjectA to compile and then configure the maven-war-plugin to exclude them, using inclusions/exclusions.
Before doing so though, you should double-check why semantically (or requirements-wise) ProjectB was set as provided in ProjectA and what would be its impact on other consumer projects.

通过在提供的范围内重新声明它不会发生这种情况。或者,您可以更改ProjectA中ProjectB的范围以进行编译,然后使用包含/排除将maven-war-plugin配置为排除它们。在此之前,您应该仔细检查为什么在ProjectA中提供的语义(或需求方式)ProjectB的设置以及它对其他消费者项目的影响。


Update
Both approaches above may suit your needs. Alternatively, as suggested in comments further options could be more sustainable and clear in the long run towards a better governance and maintenance (centralization):

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

  • Use a common parent pom where you could declare the list of shared dependencies, that is, dependencies that will be used by all children projects, defined (and maintained) once.
  • 使用公共父pom,您可以在其中声明共享依赖项列表,即所有子项目将使用的依赖项,定义(和维护)一次。

  • Use the 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 that it will only be applied whenever the dependency comes into scope and ignored otherwise). To centralize this management, again, would be better to do so in a common parent (option above).
  • 使用ProjectX中的dependencyManagement部分更改Maven依赖关系中介如何处理ProjectA上的传递依赖,而不更改ProjectA或ProjectB(类似于此答案顶部的选项1,区别在于只有在依赖关系进入时才会应用它范围,否则忽略)。再次集中管理,最好是在共同的父母(上面的选项)中这样做。