Maven mirrorOf * in settings.xml breaks the build
In our maven3 pom.xml files for a particular project, we have defined a reference to an internal Nexus repository. Since we are behind a firewall, the Nexus repository also has to be mirror of the outside world. I discovered that this generic <mirrorOf> from my settings.xml is actually evil:
<!-- settings.xml --> <mirrors> <mirror> <id>insideFirewallRepo</id> <mirrorOf>*</mirrorOf> <name>Mirror of the world outside.</name> <url>http://nexus_url/nexus/content/groups/public/</url> </mirror> </mirrors>
The reason for this being evil was our project pom files which had the following references
<properties> <nexus.url>http://nexus_url/nexus</nexus.url> <subversion.url>http://svn_url/svn</subversion.url> </properties> <scm> <connection>scm:svn:${subversion.url}/common-gwt-gui/trunk</connection> </scm> <repositories> <repository> <id>nexus-repo-releases</id> <name>Nexus Repo</name> <url>${nexus.url}/content/groups/public/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> <repository> <id>nexus-repo-snapshots</id> <name>Nexus Repo</name> <url>${nexus.url}/content/groups/public-snapshots/</url> <releases> <enabled>false</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories>[repeat the <repositories> section for <pluginRepositories>]
<distributionManagement> <repository> <id>company.releases</id> <url>${nexus.url}/content/repositories/company/</url> </repository> <snapshotRepository> <id>company.snapshots</id> <url>${nexus.url}/content/repositories/company-snapshots/</url> </snapshotRepository> </distributionManagement>
Finally we have the maven release-plugin, but this irrelevant for now:
<build> <plugins> <plugin> <artifactId>maven-release-plugin</artifactId> <configuration> <tagBase>${subversion.url}/project_name/releases</tagBase> </configuration> </plugin> </plugins> </build>
Error message: Using the wrong repository for snapshots
Now, the generic mirrorOf * in settings.xml actually overrides the specific repository information we set in the pom.xml. Because of that setting, the pom.xml <repository> is not used. And the result is an error message like this. (error message enhanced in bold)
Downloading: http://nexus_url/nexus/content/groups/public/com/company/dependency_project/1.18-SNAPSHOT/maven-metadata .xml Downloading: http://nexus_url/nexus/content/groups/public/com/company/dependency_project/1.18-SNAPSHOT/maven-metadata .xml Downloading: http://nexus_url/nexus/content/groups/public/com/company/dependency_project/1.18-SNAPSHOT/dependency_project -1.18-SNAPSHOT.pom [WARNING] The POM for com.company:dependency_project:jar:1.18-SNAPSHOT is missing, no dependency information available Downloading: http://nexus_url/nexus/content/groups/public/com/company/dependency_project/1.18-SNAPSHOT/dependency_project -1.18-SNAPSHOT.jar [INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary: [INFO] [INFO] project_name ...................................... FAILURE [1.108s] [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.364s [INFO] Finished at: Fri Jan 20 12:28:04 CET 2012 [INFO] Final Memory: 5M/15M [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal on project project_name: Could not resolve dependencies for project com.company:project_name:jar:2.1.1 3-SNAPSHOT: Could not find artifact com.company:dependency_project:jar:1.18-SNAPSHOT in insideFirewallRepo (http://nexus_url /nexus/content/groups/public/) -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/DependencyResolutionException [ERROR] [ERROR] After correcting the problems, you can resume the build with the command [ERROR] mvn <goals> -rf :project_name
Notice that the errormessage actually gave the ID of our <mirror> from settings.xml: <!-- settings.xml --> <mirrors> <mirror> <id>insideFirewallRepo</id>
<repositories> <repository><id>nexus-repo-releases</id><repository> <repository><id>nexus-repo-snapshots</id><repository>
<!-- settings.xml --> <mirrors> <mirror> <id>insideFirewallRepo</id> <mirrorOf>!nexus-repo-releases,!nexus-repo-snapshots,*</mirrorOf> <name>Mirror of the world outside.</name> <url>http://nexus_url/nexus/content/groups/public/</url> </mirror> </mirrors>
Most users could probably just remove the <mirrors> block from settings.xml, but in this particular project, that is not possible since firewall blocks for access to maven central. So, in order for us to use external dependencies, we must use the <mirror> in settings.xml
Then, you could argue, to use <proxy> instead of <mirrors> in settings.xml. This may be a decent solution as well, but in my case i wanted to avoid that, since the company proxy required user/password. Our jenkins build machines would then have my username/password, and it would lock my account whenever my password expires.
Within those constraints, the <mirror> block with excluded internal repositories seems like a decent fit.
For the issues described in this article, I have been using Maven 3.0.3 and Sonatype Nexus 1.9.2