说明
我们在利用Maven建立一个多模块的聚合工程时,可能会遇到这样的问题,那就是Could not find artifact xxx
,并且不能找到的artifact 正是父工程
项目结构
此图是我聚合工程的一个项目,在对根pom.xml进行打包的时候mvn package
报了如下错误Could not find artifact com.xxx:xxx:xxx in nexus-aliyun (https://maven.aliyun.com/repository/public)
父pom(artifactId:xxx)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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>
<groupId>com.xxx</groupId>
<artifactId>xxx</artifactId>
<packaging>pom</packaging>
<version>1.0.0</version>
<modules>
<module>xxx</module>
<module>xxxx</module>
<module>xxx/bbb</module>
</modules>
...
子pom(我只贴有问题的)(artifactId:bbb)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>xxx</artifactId>
<groupId>com.xxx</groupId>
<version>1.0.0</version>
</parent>
<version>1.0.0</version>
<modelVersion>4.0.0</modelVersion>
<artifactId>bbb</artifactId>
...
这里就有点
疑惑了,明明父工程正在package,为什么还要去找它呢,原因是出在子工程的parent就是父工程
解决方法一(不推荐)
上述工程中,子模块 bbb会去依赖父模块xxx,但是如果父模块没有install到本地时,maven就会去远程仓库取,从而导致了那样的错误,此方法的解决方法是暂时把父工程的modules
全部注释,然后install之后,在解除注释,这样的原理就是在install中把父工程给生成出来,子模块编译时自然就可以找到父模块,但这种方法的问题不仅麻烦,而且父模块还不能实时更新。所以不推荐这种方法。
最终解决
这里先说,子模块之所以要去拉远程仓库的本质是找不到父工程,虽然我们在parent声明了父工程,但是如何去得到他我们需要定义,这时候我们就要用到
relativePath
属性了
- 在默认情况下
relativePath
的默认值是../pom.xml
它是先去寻找当前工程的上级目录的pom.xml为父工程,当找不到时,就去找本地仓库,当本地仓库找不到时,就是去远程仓库。 - 我们上述工程有问题的子模块之所以出问题,是因为子模块的工程路径变成了xxx/bbb,路径结构如下
–pom.xml
–xxx
—bbb
----pom.xml
在bbb文件夹的pom.xml默认是寻找上级目录的pom.xml
,但是由于xxx不是一maven结构的工程,因此我们应该在bbb模块中配置<relativePath>../../pom.xml</relativePath>
这样在package时,便能找到父工程了,也不用每次去install父工程。
另一个细节
我们在用IDEA开发时目录结构有时会是这样
- 小箭头的文件夹图标没有被识别成模块,只是单纯的被解释成文件夹
- 大箭头的文件夹图标被识别成模块
- 所以我们还可以将
小箭头的文件夹新增一个pom.xml
来传递父引用,这样也能处理问题。