Search code examples
mavenrepositorymaven-dependency

What is the repository order that is considers by Maven when it tries to download plugins?


I don't find the documentation where Maven says how it orders the declared repositories.

Consider the following locations one could configure maven repositories:

  • settings.xml under settings/profiles/profile/repositories
    • id: settings-repo1
    • id: settings-repo2
  • settings.xml under settings/mirrors
    • id: settings-mirror1
    • id: settings-mirror2
  • parent pom.xml under project/repositories
    • id: pom-parent-repo1
    • id: pom-parent-repo2
  • child pom.xml under project/repositories
    • id: pom-child-repo1
    • id: pom-child-repo2
  • the dependencies of child pom.xml uses also repositories:
    • id: dependency-repo1
    • id: dependency-repo2

What is the order in which Maven will try to download the dependencies from all these repositories?

The mvn dependency:list-repositories command shows me a very unordered list which is hard to believe that is the real priority order.


Solution

  • I did the following to determine the order in which Maven considers the repository order:

    • I updated the URLs of all the repository/mirror settings in all the XML files to be invalid Maven repos in order to force Maven to fail
    • I ran mvn compile

    The following results are assuming that a certain dependency was never downloaded/registered in the local cache ~/.m2/repository (i.e. it was not cached or did not fail previously using other repository). If you have an entry for a certain dependency in the local cache, Maven will reuse that cached entry (which saves also the initial source repository) to try and fetch it again.

    This is what Maven tries when NO mirrors are configured:

    Downloading from settings-repo1: http://settings-repo1.org/org/apache/httpcomponents/httpclient1/4.5.6/httpclient1-4.5.6.pom
    Downloading from settings-repo2: http://settings-repo2.org/org/apache/httpcomponents/httpclient1/4.5.6/httpclient1-4.5.6.pom
    Downloading from pom-child-repo1: http://child-repo1.org/org/apache/httpcomponents/httpclient1/4.5.6/httpclient1-4.5.6.pom
    Downloading from pom-child-repo2: http://child-repo2.org/org/apache/httpcomponents/httpclient1/4.5.6/httpclient1-4.5.6.pom
    Downloading from pom-parent-repo1: http://parent-repo1.org/org/apache/httpcomponents/httpclient1/4.5.6/httpclient1-4.5.6.pom
    Downloading from pom-parent-repo2: http://parent-repo2.org/org/apache/httpcomponents/httpclient1/4.5.6/httpclient1-4.5.6.pom
    Downloading from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpclient1/4.5.6/httpclient1-4.5.6.pom
    

    and when there ARE mirrors configured:

    Downloading from settings-repo1: http://settings-repo1.org/org/apache/httpcomponents/httpclient1/4.5.6/httpclient1-4.5.6.pom
    Downloading from settings-repo2: http://settings2.org/org/apache/httpcomponents/httpclient1/4.5.6/httpclient1-4.5.6.pom
    Downloading from settings-mirror1: http://settings-mirror1.org/org/apache/httpcomponents/httpclient1/4.5.6/httpclient1-4.5.6.pom
    Downloading from settings-mirror2: http://settings-mirror2.org/org/apache/httpcomponents/httpclient1/4.5.6/httpclient1-4.5.6.pom
    Downloading from pom-parent-repo1: http://parent-repo1.org/org/apache/httpcomponents/httpclient1/4.5.6/httpclient1-4.5.6.pom
    Downloading from pom-parent-repo2: http://parent-repo2.org/org/apache/httpcomponents/httpclient1/4.5.6/httpclient1-4.5.6.pom
    Downloading from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpclient1/4.5.6/httpclient1-4.5.6.pom
    

    So the order must be:

    • settings.xml
    • current project's pom.xml
    • parent project's pom.xml

    If there are any mirrors configured, they will just replace the corresponding repositories in the original list identified by the mirrorOf element. If the mirrorOf expression identifies multiple repositories, only the first occurrence (in the Maven original order without configured mirrors) will be tried. For example, if there is a mirror (e.g. settings-mirror1) configured for: <mirrorOf>pom-parent-repo2,pom-child-repo1</mirrorOf> the repository search order will be:

    Downloading from settings-repo1: http://settings-repo1.org/org/apache/httpcomponents/httpclient1/4.5.6/httpclient1-4.5.6.pom
    Downloading from settings-repo2: http://settings-repo2.org/org/apache/httpcomponents/httpclient1/4.5.6/httpclient1-4.5.6.pom
    Downloading from settings-mirror1: http://settings-mirror1.org/org/apache/httpcomponents/httpclient1/4.5.6/httpclient1-4.5.6.pom
    Downloading from pom-child-repo2: http://child-repo2.org/org/apache/httpcomponents/httpclient1/4.5.6/httpclient1-4.5.6.pom
    Downloading from pom-parent-repo1: http://parent-repo1.org/org/apache/httpcomponents/httpclient1/4.5.6/httpclient1-4.5.6.pom
    Downloading from central: https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpclient1/4.5.6/httpclient1-4.5.6.pom
    

    As for the repositories declared in the dependency POM files, I think one should not care about them. If you have a dependency this needs to be available in one of the declared repositories (settings, parent pom, pom), otherwise the build will fail (even if you have that dependency downloaded and cached previously by another project (sub-dependency or not).