如果你已经将你的Maven
settings.xml
配置成使用Nexus作为所有公共仓库和所有公共快照仓库的镜像,你可能会遇到一些项目不能够从你的本地Nexus获取需要的构件。这很常见,因为你经常会构建一些在pom.xml
中自定义一组repositories
和snapshotRepositories
的项目。如果你正在构建开源项目,或者往你的配置中添加了自定义的第三方Maven仓库,那么这种情况就会发生。
作为一个例子,让我们试试从我们签出的源代码构件Apache Shindig。什么是Apache Shindig?对该例来说这不重要;我们需要的是一个能很容易签出和构建的样例项目。如果你实在很想知道,Shindig是在Apache Incubator中的一个围绕Google的OpenSocial API的项目。Shindig目标是提供一个允许人们运行OpenSocial小工具的容器。它给我们提供了一个有趣的样例工程,因为它有一些没有被加入到中央Maven仓库的组件,于是依赖于一些自定义的Maven仓库,使用Shindig我们可以向你展示当Nexus没有你要的构件的时候会发生什么,以及你能够使用怎样的步骤来给Nexus添加仓库。
下面的样例假设你已经安装了Subversion,并且你正在命令行运行Subversion。我们使用Subversion从Apache Incubator签出Apache Shindig然后尝试构建它。为此,执行下面的命令:
$ svn co http://svn.apache.org/repos/asf/incubator/shindig/trunk shindig ... Subversion will checkout the trunk of Apache Shindig ... $ cd shindig $ mvn install ... Maven will build Shindig ... Downloading: http://localhost:8081/nexus/content/groups/public/caja/caja/r820/caja-r820.pom Downloading: http://localhost:8081/nexus/content/groups/public/caja/caja/r820/caja-r820.jar [INFO] ------------------------------------------------------------------------ [ERROR] BUILD ERROR [INFO] ------------------------------------------------------------------------ [INFO] Failed to resolve artifact. Missing: ---------- 1) caja:caja:jar:r820 Try downloading the file manually from the project website. ... ---------- 1 required artifact is missing. for artifact: org.apache.shindig:gadgets:war:1-SNAPSHOT from the specified remote repositories: oauth (http://oauth.googlecode.com/svn/code/maven), central (http://central), apache.snapshots (http://people.apache.org/repo/m2-snapshot-repository), caja (http://google-caja.googlecode.com/svn/maven)
这个构建失败了因为它下载不到一个构件。这个构件有一个group标识符为caja
,artifactId是caja
,版本是r820
。这是一个存在于自定义仓库http://google-caja.googlecode.com/svn/maven中的一个构件。Maven没能够下载到这个构件是因为你的settings.xml
被配置成指引所有的镜像至位于我们Nexus安装的public
和public-snapshots
组。即使Apache
Shindig的pom.xml
定义了一个仓库并且将其指向了http://google-caja.googlecode.com/svn/maven,Nexus不会从一个它不知道的仓库中去获取构件。事实上,关于这次构建有两个仓库Nexus不知道:caja
和oauth
。Caja和OAuth是两个仍然处于开发中的类库。两个项目都被“发布”了,而且Shindig所依赖的版本当然不是快照版,但是这些项目没有被发布到中央Maven仓库。在我们能构建这个项目之前,我们需要想办法让Nexus知道这些仓库。
有两种方法可以解决这个问题。首先,你可以更改你的以settings.xml
覆盖特定的仓库定义符。你可以更改settings.xml
中的mirrorOf
元素为"central",而非让Nexus
public组
mirrorOf
所有的仓库。如果你这么做了,Maven就会试图直接从oauth
和caja
仓库下载依赖。这行得通,因为Maven只会为那些匹配settings.xml
中mirrorOf
元素的仓库去查阅Nexus。如果Maven看到一个仓库定义符caja
或者oauth
,而且没有在你的settings.xml
中看到一个镜像,它会直接去连接这个仓库。
第二种方法,更有趣的选择是添加这些仓库至Nexus,并且添加这些仓库至public组。