如何从父pom继承依赖到子pom
Posted
技术标签:
【中文标题】如何从父pom继承依赖到子pom【英文标题】:How to inherit dependency from a parent pom to a child pom 【发布时间】:2016-12-17 08:35:35 【问题描述】:我是使用 maven 和 jenkins 的新手。我正在尝试将依赖项从父 pom 继承到子 pom 它显示以下错误:
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/wss/util/XMLConverters.java:[10,26] package com.rpmtec.current does not exist
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/wss/util/XMLConverters.java:[11,26] package com.rpmtec.current does not exist
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/wss/util/XMLConverters.java:[15,38] cannot find symbol
symbol: class AbstractRequestMessageData_Type
location: class com.td.inv.wss.util.XMLConverters
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/wss/util/XMLConverters.java:[26,23] cannot find symbol
symbol: class AbstractResponseMessageData_Type
location: class com.td.inv.wss.util.XMLConverters
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/wss/util/UsTermRateItemComparator.java:[5,42] package com.rpmtec.current.UsTermRate_Type does not exist
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/wss/util/UsTermRateItemComparator.java:[7,61] cannot find symbol
symbol: class UsTermRateItems
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/wss/util/UsTermRateItemComparator.java:[9,28] cannot find symbol
symbol: class UsTermRateItems
location: class com.td.inv.wss.util.UsTermRateItemComparator
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/wss/util/UsTermRateItemComparator.java:[9,48] cannot find symbol
symbol: class UsTermRateItems
location: class com.td.inv.wss.util.UsTermRateItemComparator
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/model/COIRQ.java:[9,40] package com.fasterxml.jackson.annotation does not exist
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/model/COIRQ.java:[10,26] package com.rpmtec.current does not exist
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/model/COIRQ.java:[11,26] package com.rpmtec.current does not exist
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/model/COIRQ.java:[12,26] package com.rpmtec.current does not exist
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/model/COIRQ.java:[13,26] package com.rpmtec.current does not exist
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/model/COIRQ.java:[14,42] package com.rpmtec.current.UsTermRate_Type does not exist
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/model/COIRQ.java:[19,2] cannot find symbol
symbol: class JsonIgnoreProperties
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/model/COIRQ.java:[69,22] cannot find symbol
symbol: class ORCA_GETTERMHOLDINGRS_Type
location: class com.td.inv.model.COIRQ
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/model/COIRQ.java:[69,66] cannot find symbol
symbol: class RPM_GETPLANACCOUNTOVERVIEWRS_Type
location: class com.td.inv.model.COIRQ
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/model/COIRQ.java:[70,25] cannot find symbol
symbol: class ORCA_GETTERMINSTRUCTIONRS_Type
location: class com.td.inv.model.COIRQ
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/wss/util/RPMInvoker.java:[5,26] package javax.ws.rs.client does not exist
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/wss/util/RPMInvoker.java:[6,26] package javax.ws.rs.client does not exist
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/wss/util/RPMInvoker.java:[7,26] package javax.ws.rs.client does not exist
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/wss/util/RPMInvoker.java:[8,26] package javax.ws.rs.client does not exist
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/wss/util/RPMInvoker.java:[9,24] package javax.ws.rs.core does not exist
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/wss/util/RPMInvoker.java:[15,26] package com.rpmtec.current does not exist
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/wss/util/RPMInvoker.java:[16,26] package com.rpmtec.current does not exist
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/wss/util/RPMInvoker.java:[23,57] cannot find symbol
symbol: class AbstractRequestMessageData_Type
location: class com.td.inv.wss.util.RPMInvoker
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/wss/util/RPMInvoker.java:[24,41] cannot find symbol
symbol: class AbstractResponseMessageData_Type
location: class com.td.inv.wss.util.RPMInvoker
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/wss/application/InvestmentAPI.java:[4,19] package javax.ws.rs does not exist
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/wss/application/InvestmentAPI.java:[5,24] package javax.ws.rs.core does not exist
[ERROR] /D:/jenkins/workspace/CBAW/testP/WSW_Investment/src/main/java/com/td/inv/wss/application/InvestmentAPI.java:[9,36] cannot find symbol
symbol: class Application
这是我的父 POM:
.....
<modelVersion>4.0.0</modelVersion>
<groupId>group1</groupId>
<artifactId>group1-artifact</artifactId>
<version>1.0.1</version>
<packaging>pom</packaging>
<modules>
<module>child1</module>
</modules>
.......
这是我的孩子 POM:
.....
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>group1</groupId>
<artifactId>group1-artifact</artifactId>
<version>1.0.1</version>
<relativePath>(full url.....)/jenkins-parent-pom//pom.xml</relativePath>
</parent>
<groupId>group1</groupId>
<artifactId>child1</artifactId>
<version>0.0.1</version>
<packaging>war</packaging>
......
这是我尝试从父 POM 继承子 POM 中的依赖项的方式:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>group1</groupId>
<artifactId>group1-artifact</artifactId>
<version>1.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
如果我将这些相同的依赖项放在子 POM 中,它会完美运行。我使用 clean install
进行安装,deploy
使用 jenkins 在 nexus 中进行部署。我正在使用 maven-3.3.9。在 jenkins 中,我从 git 阅读了两个不同的 maven 项目中的父子 pom。我想从父 POM 继承所有依赖项和插件。可能吗?
【问题讨论】:
【参考方案1】:您应该在<dependencies>
部分下声明要继承的依赖项以实现此目的。 <dependencyManagement>
用于以后必须在需要时在特定子级的<dependencies>
中引用才能生效的定义。
更新:在声明每个子 pom 将继承的依赖项时要小心。很快你就会得到你并不真正需要的依赖,因为它们是在父级中声明的。正如其他评论者所提到的,<dependencyManagement>
可能是更好的选择,尽管它不是您最初想要的。
【讨论】:
你的意思是,在父 pom 中我应该在<dependencies>
而不是 <dependencyManagement>
中声明它们。另一方面,在<dependencyManagement>
中声明的依赖项只能在您需要在子 pom 中使用时使用——您只需在该子的<dependencies>
中写入其组和工件。好处是其他属性(版本)只在父级中声明一次。
谢谢。是的,我的目标是继承对子 pom 的特定依赖项。只是为了确保,根据您的回复,我会将这些特定的依赖项放在父 pom 中的 事实上,你有两种方法来处理这个问题。
-
要么在
<dependencyManagement />
节点下的父 pom 中考虑依赖关系,在每个需要它的子节点中,将依赖关系添加到 <dependencies />
节点中。您可以选择不设置依赖的版本。
或者你在<dependencies />
节点的父pom中声明依赖,每个子都会从依赖中受益。
例如,如果你在父 pom 中声明:
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.21</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</dependencyManagement>
那么slf4j-api
将成为所有子级的依赖项。但是,如果需要,您必须在孩子的 pom 中添加对 slf4j-simple
的依赖:
<dependencies>
<dependency>
<group>org.slf4j</group>
<artifactId>slf4j-simple</artifactId>
</dependency>
</dependencies>
对于插件,它的工作原理相同,但使用 <pluginManagement />
和 <plugins />
节点。所有配置都可以在父 pom 的插件定义中进行,您只需在子 pom 的 <build />
部分中声明插件即可。
【讨论】:
谢谢。但是如果不在<dependencies />
节点中,则不需要在子 pom 中添加依赖项。这是你的选择。
虽然你当然可以这样做,但将<dependencies />
放在<dependencyManagement />
之外的父pom 中并不是一个好主意。您的所有子模块将始终继承所有这些依赖项。任何其他可能使用您的模块之一的项目也将暂时获得所有这些 dep 并且可能发生冲突或更糟,特别是如果该子模块不使用所有这些。 @ArthurNoseda 的原始解决方案是最好的。
以及如何通过子项目使用父项目的类?【参考方案3】:
下面是如何使用父子pom的示例。
父pom如下:
.....
<modelVersion>4.0.0</modelVersion>
<groupId>group1</groupId>
<artifactId>group1-artifact</artifactId>
<version>1.0.1</version>
<packaging>pom</packaging>
<modules>
<module>child1</module>
// add more childs here
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.abc</groupId>
<artifactId>xyz</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</dependencyManagement>
.......
如果你在dependencyManagement
标签中指定了一个依赖,它仅仅意味着你让这个jar 可用于子pom。此时它不会实际下载 jar。子 pom 必须提供 groupId
和 artifactId
明确 下载并使用 jar 编译其类。 注意:您不必在子 pom 中包含依赖项的版本。
子pom如下:
.....
<modelVersion>4.0.0</modelVersion>
<parent> // this is how you will inherit from parent pom
<groupId>group1</groupId>
<artifactId>group1-artifact</artifactId>
<version>1.0.1</version>
</parent>
<groupId>child1</groupId>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<scope>runtime</scope>
// no version needed as it would inherit from the parent pom
</dependency>
<dependency>
<groupId>org.abc</groupId>
<artifactId>xyz</artifactId>
// no version needed as it would inherit from the parent pom
</dependency>
</dependencies>
.......
最好将所有子级的公共依赖项放在父级 pom 的 dependencyManagement
标记中。这样您就可以从一个地方管理这些依赖项的版本。
【讨论】:
以及如何通过子项目使用父项目的类? 不是pom类型的父项目吗?里面不应该有任何类。 是的,@ArthurNoseda 是正确的。您的父 pom 通常是 pom 类型,而不是 jar 或 war。理想情况下,父 pom 不会有任何代码。它的主要目的是充当所有子 pom 的聚合器。 如果我希望在子 pom 中使用时在依赖项中发生排除,我可以从父项中排除父 pom.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
</parent>
<groupId>com.ll</groupId>
<artifactId>parent-module</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<!-- child will inherit all content -->
<dependencies>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.11.0</version>
</dependency>
</dependencies>
<!-- child will inherit only version-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.5.7</version>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>sub-module1</module>
<module>sub-module2</module>
</modules>
</project>
子 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.ll</groupId>
<artifactId>parent-module</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<groupId>com.ll</groupId>
<artifactId>sub-module1</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</dependency>
</dependencies>
</project>
1.child will use zookeeper:3.5.7, the version is from parent pom.xml <dependencyManagement>:<dependencies>:<dependency>.
2.child will use protobuf-java:3.11.o, it is from parent pom.xml <dependencies>:<dependency>.
【讨论】:
【参考方案5】:<dependencyManagement>
中添加的任何内容都会自动添加到孩子的 pom 中。唯一需要注意的是,在孩子的 pom 中,我们不需要显式添加版本,否则这将是仅可用于子模块的其他依赖项。
parent_pom.xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
</dependencies>
</dependencyManagement>
child_pom.xml
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
【讨论】:
以上是关于如何从父pom继承依赖到子pom的主要内容,如果未能解决你的问题,请参考以下文章
子 pom 可以从自定义父 pom 的 spring-boot-starter-parent 继承插件管理和依赖管理吗?