69

Where is the best place to specify required repositories for maven projects, pom.xml or settings.xml? What are the pros and cons of each location? What is best practice?

It seems to me that defining the repositories in the POM is better for a number of reasons:

  • Reproducibility: The dependent artifacts are coming from a known location that is explicitly declared in the POM. There is also less opportunity for a user's misconfigured repositories to cause problems.
  • Portability: This POM will build on anyone's machine with maven installed. There are no additional requirements on additional user configured repository settings.
  • Ease of use: It's easier for new developers to retrieve and build the project because there is less configuration to setup.

Perhaps a con is that if the location of the repository changes in the future, proxies need to be installed or patch releases of old software need to be released specifying the new repository locations (or .m2/settings.xml can always provide additional repositories as a last resort). However, this seems like a necessary ramification of good reproducibility and portability in release management rather than a con.

Any other thoughts?

akauppi
  • 17,018
  • 15
  • 95
  • 120
jnorris
  • 6,350
  • 8
  • 30
  • 33
  • 2
    If the repo location changes, you simply update the pom and make sure everyone refreshes their local copy. – Péter Török Feb 08 '10 at 23:09
  • Right, but older versions have likely been released as a distribution (eg: zip, tar.gz). One nice benefit of reproducibility is that you can take any distribution/version, apply a patch for whatever reason and you're guaranteed to get the exact functional distribution plus your patch and nothing else. – jnorris Feb 08 '10 at 23:13
  • 1
    My opinion exactly mirrors @jnorris but Sonatype offers some points to consider (maybe outdated?) about keeping URLs out of your distributed POM files: http://blog.sonatype.com/2009/02/why-putting-repositories-in-your-poms-is-a-bad-idea/ – chrisinmtown Dec 26 '17 at 16:30

3 Answers3

65

Where is the best place to specify required repositories for maven projects, pom.xml or settings.xml? What are the pros and cons of each location? What is best practice?

I'd personally define the repositories required by a particular project in the project pom.xml because it keeps the build portable. The settings.xml file should be used for user specific or secret things only in my opinion. No really, asking the user to add repository locations, even if this is properly documented, somehow defeats one of maven's feature (transparent dependency handling) and I don't like this idea.

The only "good" use case I can think of for using settings.xml to deal with repositories is when you have a corporate repository and want Maven to use this repository instead of public ones. For example, to avoid connections to any public repository, you would declare the corporate repository as a mirror of all of them:

<settings>
  ...
  <mirrors>
    <mirror>
      <id>proxy-of-entire-earth</id>
      <mirrorOf>*</mirrorOf>
      <name>Maven Repository Manager running on repo.mycompany.com</name>
      <url>http://repo.mycompany.com/proxy</url>
    </mirror>
  </mirrors>
  ...
</settings>
Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
  • +1. This cleared up the "what-ifs" I was thinking of when wrestling with this question myself. 1) What if the mirror "goes away" and you need to provide a new one (if the project is not maintained and you want to keep the source tree pristine)? Set up a mirror in settings.xml 2) What if you want to use a private local repot only in certain environments? Use a wildcard mirror in settings.xml as you've suggested. – Merlyn Morgan-Graham Sep 21 '12 at 06:46
  • FWIW, this info is now also in the Maven docs http://maven.apache.org/guides/mini/guide-mirror-settings.html#Using_A_Single_Repository – Leif Gruenwoldt Apr 03 '13 at 19:00
  • 1
    If you have a corporate repo and you are building a project for a customer and you have to deliver the source code at the end you better configure the repos in settings.xml. You don't want your Artifactory (or similar) to be reached every time the project is built outside your office. – spekdrum Jul 23 '18 at 11:51
12

I'll give you three reasons why you should consider storing repository URLs in settings.xml instead of pom.xml:

  1. spekdrum mentioned something that has actually happened to us:

If you have a corporate repo and you are building a project for a customer and you have to deliver the source code at the end you better configure the repos in settings.xml. You don't want your Artifactory (or similar) to be reached every time the project is built outside your office.

  1. The guys at Sonatype recommend placing URLs in settings.xml.

  2. If the dependency repository goes down (think java.net) you only have to correct the URL in one place. If you used pom.xml all previous releases are broken. You potentially have to commit a fixed pom.xml per release version.

Is configuring URLs in settings.xml more work than pom.xml? Absolutely.

Does it buy you more flexibility? Absolutely.

Here is what settings.xml should look like:

<settings>
    <profiles>
        <profile>
            <id>mycompany-servers</id>
            <repositories>
                <repository>
                    <id>mycompany-release</id>
                    <url>https://mycompany.com/release/</url>
                    <snapshots>
                        <enabled>false</enabled>
                    </snapshots>
                </repository>
                <repository>
                    <id>mycompany-snapshot</id>
                    <url>https://mycompany.com/snapshot/</url>
                    <releases>
                        <enabled>false</enabled>
                    </releases>
                </repository>
            </repositories>
        </profile>
    </profiles>
    <activeProfiles>
        <activeProfile>mycompany-servers</activeProfile>
    </activeProfiles>
    <servers>
        <server>
            <id>mycompany-release</id>
            <username>your-username</username>
            <password>your-api-key</password>
        </server>
        <server>
             <id>mycompany-snapshot</id>
             <username>your-username</username>
             <password>your-api-key</password>
        </server>
    </servers>
</settings>
Gili
  • 86,244
  • 97
  • 390
  • 689
4

I always put URLs in the POM and passwords in settings.xml. If you put URLs in settings.xml, you require your users to update files on their local systems if your URL ever changes. If the URL is specified in your POM, you can change it and push a new release. URLs change more often than most can predict and lead to frustrated users when the build breaks.

Passwords are kept in settings.xml for obvious reasons. Passwords should never be kept in version control. You'll need passwords for mvn deploy functionality to deploy to remote repositories.

Steven
  • 2,189
  • 3
  • 15
  • 12
  • To see a sample on how ~/.m2/settings.xml should be set up, see http://stackoverflow.com/questions/2941605/sample-settings-xml-for-maven – akauppi Jun 30 '16 at 11:34