如何解析Maven仓库?

huangapple go评论71阅读模式
英文:

How maven repositories are resolved?

问题

让我们假设我的 settings.xml 如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd" xmlns="http://maven.apache.org/SETTINGS/1.1.0"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <profiles>
   <profile>
     <repositories>
       <repository>
         <snapshots>
           <enabled>false</enabled>
         </snapshots>
         <id>central</id>
         <name>libs-release</name>
         <url>http://artifactory.ark.local:8080/libs-release</url>
       </repository>
       <repository>
            <id>vmware-repo</id>
            <name>VM Nexus Repo</name>


<details>
<summary>英文:</summary>

Let&#39;s say my `settings.xml` is defined like below

    &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
    &lt;settings xsi:schemaLocation=&quot;http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd&quot; xmlns=&quot;http://maven.apache.org/SETTINGS/1.1.0&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&gt;
     &lt;profiles&gt;
       &lt;profile&gt;
         &lt;repositories&gt;
           &lt;repository&gt;
             &lt;snapshots&gt;
               &lt;enabled&gt;false&lt;/enabled&gt;
             &lt;/snapshots&gt;
             &lt;id&gt;central&lt;/id&gt;
             &lt;name&gt;libs-release&lt;/name&gt;
             &lt;url&gt;http://artifactory.ark.local:8080/libs-release&lt;/url&gt;
           &lt;/repository&gt;
           &lt;repository&gt;
                &lt;id&gt;vmware-repo&lt;/id&gt;
                &lt;name&gt;VM Nexus Repo&lt;/name&gt;
                &lt;url&gt;http://build-squid.eng.vm.com/nexus/content/groups/repo&lt;/url&gt;
                &lt;releases&gt;
                    &lt;enabled&gt;true&lt;/enabled&gt;
                &lt;/releases&gt;
                &lt;snapshots&gt;
                    &lt;enabled&gt;false&lt;/enabled&gt;
                &lt;/snapshots&gt;
            &lt;/repository&gt;
           &lt;repository&gt;
             &lt;snapshots /&gt;
             &lt;id&gt;snapshots&lt;/id&gt;
             &lt;name&gt;libs-snapshot&lt;/name&gt;
             &lt;url&gt;http://artifactory.ark.local:8080/libs-snapshot&lt;/url&gt;
           &lt;/repository&gt;
         &lt;/repositories&gt;
         &lt;pluginRepositories&gt;
           &lt;pluginRepository&gt;
             &lt;snapshots&gt;
               &lt;enabled&gt;false&lt;/enabled&gt;
             &lt;/snapshots&gt;
             &lt;id&gt;central&lt;/id&gt;
             &lt;name&gt;plugins-release&lt;/name&gt;
             &lt;url&gt;http://artifactory.ark.local:8080/plugins-release&lt;/url&gt;
           &lt;/pluginRepository&gt;
           &lt;pluginRepository&gt;
             &lt;snapshots /&gt;
             &lt;id&gt;snapshots&lt;/id&gt;
             &lt;name&gt;plugins-snapshot&lt;/name&gt;
             &lt;url&gt;http://artifactory.ark.local:8080/plugins-snapshot&lt;/url&gt;
           &lt;/pluginRepository&gt;
         &lt;/pluginRepositories&gt;
         &lt;id&gt;artifactory&lt;/id&gt;
       &lt;/profile&gt;
     &lt;/profiles&gt;
     &lt;activeProfiles&gt;
       &lt;activeProfile&gt;artifactory&lt;/activeProfile&gt;
     &lt;/activeProfiles&gt;
    &lt;/settings&gt; 

In a multimodule project of the form

    main
    	storage
    		metrics
    		config
    	common

Let&#39;s say in `metrics` pom if a repository is added.

    &lt;repository&gt;
      &lt;id&gt;cloudera&lt;/id&gt;
      &lt;url&gt;https://repository.cloudera.com/artifactory/cloudera-repos/&lt;/url&gt;
    &lt;/repository&gt;

 1. If a dependency is defined in `A` which is present in both cloudera
    repo and local nexus repo how maven will resolve the repository?
    Will it first try to download from cloudera repo and if there is
    some problem then it will go in local nexus repo or it will check
    only in cloudera repo and if it is not present it will give error
    without trying from local nexus repo?
    
 2. Does the answer to the above question change based on if `A` is defined
    as a dependency in `metric` or some other pom where repository is not
    defined?
 
Maven Version - 3.6.3

</details>


# 答案1
**得分**: 0

这已经在[maven邮件列表][1]中得到了解答。这里重新发布答案:

&gt; 答案取决于以下因素;
&gt; 
&gt; 1) 它是一个发布版本还是快照版本。如果发布版本在本地存储库中,那么不会检查远程存储库。2) 排序您的pom执行的顺序
&gt; 
&gt; 我已经用中央存储库和公司存储库简化了您的配置文件,Aa、Ab和Ac是相同的GAV,但在解释中这样做会更容易知道我在谈论哪个A。
&gt; 
&gt; 配置
&gt; - 中央存储库(包含Aa)
&gt; - 公司存储库(包含Ab)
&gt; 
&gt; 父pom
&gt; - alpha
&gt; -- A
&gt; - bravo(有额外的R存储库,类似于您的cloudera,包含Ac)
&gt; -- A
&gt; - charlie
&gt; -- A
&gt; 
&gt; 对于发布版本,假设本地存储库为空。
&gt; - 这次的构建顺序是alpha,bravo,charlie
&gt; - Alpha需要A,Aa作为它在中央存储库中,并且这是列表中的第一个存储库
&gt; - Bravo需要A,它在本地存储库中看到Aa并使用它
&gt; - Charlie需要A,它在本地存储库中看到Aa并使用它
&gt; 
&gt; 与之前相同,但maven认为构建顺序是bravo,alpha,charlie,
&gt; 即您更改了内部依赖关系或重新排序了模块部分。
&gt; - Bravo需要A,并且Ac作为它在R存储库中,并且这是列表中的第一个存储库,我认为这是pom存储库,然后是父pom,然后是设置文件。
&gt; - Alpha需要A,它在本地存储库中看到Ac并使用它
&gt; - Charlie需要A,它在本地存储库中看到Ac并使用它
&gt; 
&gt; 接下来是如果A是一个-SNAPSHOT依赖,假设本地存储库为空,Aa为v 1-1,Ab为v1-1,Ac为v1-1
&gt; - 这次的构建顺序是alpha,bravo,charlie
&gt; - Alpha需要A,Aa作为它在中央存储库中,并且这是列表中的第一个存储库,但它有一个Ab存在的缓存
&gt; - Bravo需要A,它看到它没有来自R存储库的A的缓存,因此从R存储库中查找A,如果R存储库中的Ac更新,则下载并使用Ac。在这种情况下,Aa更新,所以使用Aa。
&gt; - Charlie需要A,它看到所有存储库都有A的缓存,并且只使用本地存储库中的A,在这种情况下使用Aa。
&gt; 
&gt; 接下来是如果A是一个-SNAPSHOT依赖,假设本地存储库为空,Aa为v 1-1,Ab为v1-1,Ac为v1-2
&gt; - 这次的构建顺序是alpha,bravo,charlie
&gt; - Alpha需要A,Aa作为它在中央存储库中,并且这是列表中的第一个存储库,但它有一个Ab存在的缓存
&gt; - Bravo需要A,它看到它没有来自R存储库的A的缓存,因此从R存储库中查找A,如果R存储库中的Ac更新,则下载并使用Ac。在这种情况下,Ac更新,所以使用Ac。
&gt; - Charlie需要A,它看到所有存储库都有A的缓存,并且只使用本地存储库中的A,在这种情况下使用Ac。
&gt; 
&gt; 
&gt; 
&gt; 如您所见,当使用-SNAPSHOT版本并且不同的pom具有存储库时,情况可能会变得非常混乱。这是我在构建过程的实际操作经验中进行试验、调试和故障排除的结果。
&gt; 
&gt; 希望对您有所帮助。
&gt; 
&gt; John

  [1]: https://mail-archives.apache.org/mod_mbox/maven-users/202007.mbox/%3CCAH9u10nPZLSD5yvu4bM-eTMFZ93_RAkCAKOsbvpbMwP5S%3DR8bA%40mail.gmail.com%3E

<details>
<summary>英文:</summary>

This has been answered in the [maven mailing list][1]. Just re-posting the answer here

&gt; The answer depends on the following;
&gt; 
&gt; 1) is it a release version or snapshot version. As if the release
&gt; version is in local repo then no remote repo&#39;s are checked. 2) order
&gt; your pom&#39;s are executed
&gt; 
&gt; I&#39;ve simplified your profiles with central repo and company repo, and
&gt; Aa, Ab and Ac are the same GAV but it&#39;s just so in the explanation
&gt; it&#39;s easier to know what A i&#39;m talking about.
&gt; 
&gt; settings
&gt; - central repo (contains Aa)
&gt; - company repo (contains Ab)
&gt; 
&gt; parent-pom
&gt; - alpha
&gt; -- A
&gt; - bravo (has extra R repository like your cloudera, contains Ac)
&gt; -- A
&gt; - charlie
&gt; -- A
&gt; 
&gt; For release version assuming empty local repo.
&gt; - Build order this time alpha, bravo, charlie
&gt; - Alpha needs A, and Aa is downloaded as it&#39;s in central repo and that was 1st repo in the order list
&gt; - Bravo needs A, it sees Aa in local repo and uses it
&gt; - Charlie needs A, it sees Aa in local repo and uses it
&gt; 
&gt; Same as before but maven believe build order is bravo, alpha, charlie,
&gt; i.e. you&#39;ve changed an internal dependency or reorder you modules
&gt; section.
&gt; - Bravo needs A, and Ac is downloaded as it&#39;s in R repo and that was 1st repo in the order list, which i think it&#39;s pom repo&#39;s then parent
&gt; pom&#39;s then settings file.
&gt; - Alpha needs A, it sees Ac in local repo and uses it
&gt; - Charlie needs A, it sees Ac in local repo and uses it
&gt; 
&gt; Next is if A is a -SNAPSHOT dependency assuming empty local repo, Aa
&gt; is v 1-1, Ab is v1-1 and Ac is v1-1
&gt; - Build order this time alpha, bravo, charlie
&gt; - Alpha needs A, and Aa is downloaded as it&#39;s in central repo and that was 1st repo in the order list, but it has a cache of Ab existing
&gt; - Bravo needs A, it sees it doesn&#39;t have a cache of A from R repo, so looks up A from R repo, and if Ac in R repo is newer it is downloaded
&gt; and used. in this case Aa is newer so Aa is used.
&gt; - Charlie needs A, it sees all repo&#39;s have caches of A, and just uses the A in the local repo, in this case Aa is used.
&gt; 
&gt; Next is if A is a -SNAPSHOT dependency assuming empty local repo, Aa
&gt; is v 1-1, Ab is v1-1 and Ac is v1-2
&gt; - Build order this time alpha, bravo, charlie
&gt; - Alpha needs A, and Aa is downloaded as it&#39;s in central repo and that was 1st repo in the order list, but it has a cache of Ab existing
&gt; - Bravo needs A, it sees it doesn&#39;t have a cache of A from R repo, so looks up A from R repo, and if Ac in R repo is newer it is downloaded
&gt; and used. in this case Ac is newer so Ac is used.
&gt; - Charlie needs A, it sees all repo&#39;s have caches of A, and just uses the A in the local repo, in this case Ac is used.
&gt; 
&gt; 
&gt; 
&gt; As you can see it can get very messy when -SNAPSHOT&#39;s are being used
&gt; and different pom&#39;s have repo. This is my hands-on experience of trial
&gt; and error, debugging and troubleshooting of build processes.
&gt; 
&gt; Hope it was helpful.
&gt; 
&gt; John

  [1]: https://mail-archives.apache.org/mod_mbox/maven-users/202007.mbox/%3CCAH9u10nPZLSD5yvu4bM-eTMFZ93_RAkCAKOsbvpbMwP5S%3DR8bA%40mail.gmail.com%3E

</details>



huangapple
  • 本文由 发表于 2020年7月24日 17:51:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/63071141.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定