这阵子碰了一个Maven的坑 无法下载pom中的插件
项目报错:
Plugin org.apache.maven.plugins:maven-resources-plugin:2.6 or one
of its dependencies could not be resolved: Failed to read artifact
descriptor for org.apache.maven.plugins:
maven-resources-plugin:jar:2.6: Could not transfer artifact org.apache.maven.plugins:maven-resources-plugin:pom:2.6
from/to alimaven
报错信息是无法从阿里云镜像下载相应的maven插件,在网上搜了一通,知道了和settings中配置的Maven镜像有关系,但网上并没有能直接解决问题的博文。 所以去翻阅了Maven的官方文档,了解了mirrorOf标签的含义,结合自己的测试,解决了该问题。
maven官方文档mirrorOf标签
<mirror>
<id>A仓库的id</id>
<name>xxx</name>
<url>A仓库的url</url>
<mirrorOf>B仓库的id</mirrorOf>
</mirror>
如何理解以上标签中的镜像设置呢?
首先要知道id和url是一伙的,mirrorOf是一伙的:
id的作用是定位唯一的maven仓库A,url是该仓库A的url,mirrorOf标签中需要填的另一个仓库的id(同样,该id可以唯一定位一个仓库B)
当maven项目准备从仓库B下载依赖时,会对settinngs.xml中设置的镜像进行匹配,实际上就是看哪个镜像中mirrorOf的值指向了B,显然上述的配置是满足的,则转而从A下载依赖。 可见镜像,其实就是代理;将A设置为B的镜像,原本通过B下载的依赖会转为从A下载
maven官方文档中有这句话:
Note that there can be at most one mirror for a given repository. In other words, you cannot map a single repository to a group of mirrors that all define the same <mirrorOf> value. Maven will not aggregate the mirrors but simply picks the first match.
即,不要为一个仓库配置多个镜像,e.g. 仓库A和仓库C都被设置为B的镜像,可以想象,当有一个需要从B下载的依赖时,到底是走A还是走C呢?所以Maven不推荐这么配置,虽然不会报错,但Maven默认会以第一个为准(A写在C之前则使用A)
MirrorOf标签除了可以写仓库的id还可以使用通配符进行匹配:
<mirror>
<id>internal-repositoryid>
<name>Maven Repository Manager running on repo.mycompany.comname>
<url>http://repo.mycompany.com/proxyurl>
<mirrorOf>*mirrorOf>
mirror>
mirrors>
显然,* 匹配所有的下载请求,此配置意味着所有的请求都被转为从interal-repository下载
那么问题来了,通常大家都是在配置文件中配置多个文件,当 * 和 id 同时存在会如何呢?
e.g.
<mirror>
<id>huaweicloud</id>
<mirrorOf>*</mirrorOf>
<url>https://mirrors.huaweicloud.com/repository/maven/</url>
</mirror>
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://central.maven.org/maven2</url>
<mirrorOf>central</mirrorOf>
</mirror>
我配了一个华为云镜像和一个阿里云镜像,二者的mirrorOf分别是 * 和central,当我们下载一个本该从中央仓库下载的依赖时,二者都是符合的,那么到底是匹配到 * 还是匹配到 central呢 即是走华为云还是走阿里云呢?
官方文档:
可见 精确匹配 > 通配符匹配,所以走的是阿里云
以上的华为云和阿里云正是导致我项目报错的配置,然而此时阿里云仓库找不到相应的插件,所以报错了;将华为云的mirrorOf标签改为central,此时由于二者mirrorOf的值相同且华为云在前,所以走的是华为云
更改完了配置,发现IDEA中的下载链接果然变成了华为云,顺利从华为云上下载了该插件,问题解决