Recently I’ve been trying to set up a new machine with a maven build that can work offline. My first instinct was to do the following:
- Configure maven with a ~/.m2/settings.xml file with our set of Nexus repos (we use six or seven locally hosted Nexus repos)
- Run an online build to cache all the artifacts in the local maven repo
- Delete the ~/.m2/settings.xml file with the repo definitions in
- Run an offline build with -o and confirm it works
Much to my surprise, this process failed with a bunch of errors like the following:
[ERROR] Plugin org.apache.maven.plugins:maven-resources-plugin:2.7 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.apache.maven.plugins:maven-resources-plugin:jar:2.7: The repository system is offline but the artifact org.apache.maven.plugins:maven-resources-plugin:pom:2.7 is not available in the local repository.
I couldn’t really see what was going on here. The missing artifacts were all definitely in the local repo. I ended up downloading the Maven source and debugging into it. The problem is that when Maven downloads a file from a remote repo, it stores a file called _maven.repositories along with the artifact in the local cache, that says where it was obtained from. The file format is like this:
#NOTE: This is an internal implementation file, its format can be changed without prior notice.
#Tue Jun 23 14:39:00 BST 2015
When trying to resolve an artifact, if the artifact is found locally, maven then attempts to determine if it is a locally installed artifact, or something cached from a remote download. The problem I was seeing is that if it finds a _maven.repositories file with the name of a repo that is not in your settings.xml, it throws an exception! To me, either Maven should permit this artifact to be used, or if the maven developers really don’t want that to happen, the wording of the exception should make clear what is actually going on. e.g. “I found file XYZ.jar in the local repo, but the _maven.repositories file tells me it was downloaded from a repo called MyRepo which isn’t configured for the current build, therefore I’m not using it”.
For now, if you want your offline build to work, you have two options:
- Download your proprietary jars from your Nexus repo like I did, but don’t delete your settings.xml
- Install your proprietary jars manually, so there is no _maven.repositories file to confuse maven