2017-08-17 23 views
0

當我查看本地Maven緩存(~/.m2/repository/)時,我看到某些工件的10-20個版本,其中一些僅用於單個特定構建(項目)。我想擺脫這種重複(確實,它們是不同的版本,但我仍然認爲依賴項目將能夠容忍微觀或次要版本的差異),並以某種方式要求Maven訴諸最接近的可用版本在依賴關係解析期間,如果本地存儲庫中缺少特定的工件版本。讓Maven用最接近的可用匹配來解決缺失的依賴關係

舉例來說,如果我有1.0.0版本,1.1.21.4.0在我的本地緩存中foo:bar神器2.0.0,我想Maven來:對於需要1.1.0

  • 使用一個構建

    • 使用1.1.21.4.0需要構建1.4.10
    • 使用2.0.0構建需要2.5.0

    而不必手動更改特定構建的pom

    我非常瞭解在沒有正確分析的情況下切換依賴版本的風險,我只是要求一種機制來用於非關鍵構建(例如我剛剛克隆的一個工具/庫VCS,並希望運行並嘗試),最好只在提供特定標誌時激活。

    那裏有東西,像Maven擴展或插件(可以在系統範圍內應用,並根據需要用標誌激活),這可以幫助我實現我的目標嗎?

    PS:自定義「最近的」可能是模糊的(鑑於行家可能不知道的1.4.02.0.0接近1.5.0取決於位於它們之間的實際發行版本)時,它甚至會是足夠如果我可以在構建命令中指定版本(例如mvn package -Dfoo:bar=1.4.0),仍然不會進行任何手動pom更改。 (雖然對於已指定爲<properties>條目的版本,這可能已經是可能的了,但我想要一個通用解決方案,即使傳遞依賴關係中的硬編碼版本也可以被覆蓋。)

    PPS:請注意項目)將不會由我創作/編寫,所以我沒有真正的控制/權限對他們的實際pom文件。我正在尋找的是一種方法來覆蓋其pom文件中的依賴項版本,而無需在源代碼級進行任何手動修改。

  • +0

    maven中的版本可以是範圍。你讀過[POM參考](https://maven.apache.org/pom.html),「依賴版本需求規格」一節嗎? –

    +0

    @PaulHicks謝謝,但我指的是構建任意庫(比如我剛剛克隆的一個VCS),它的'pom'不是由我組成的(我寧願避免在構建之前手動更改它們)。 Btw對不起,如果單詞「(寵物)項目」是誤導性的,我會刪除它:) –

    +0

    這是什麼依賴管理的目的。你的pom定義了你接受的版本/版本範圍。如果第三方pom依賴於第四方(p。pom)(比如版本1.2),則可以排除該父項目中該項目的臨時依賴關係,並且自己包含正確的版本或版本範圍。我一直都在爲使用5.0.0-RC2編寫依賴於JUnit 4.12的項目而努力...... –

    回答

    1

    爲了更改傳遞依賴關係,您需要排除直接依賴關係中的傳遞依賴關係,然後在您的pom中添加直接依賴關係。例如,如果您對foo.jar(取決於xyz.jar版本1.3)和bar.jar(取決於xyz.jar版本1.4)有依賴關係,那麼您可以在這兩個部分中包含這兩個部分POM:

    <!-- Define the version(s) that you allow your dependencies to depend on. --> 
    <dependencyManagement> 
        <dependency> 
        <groupId>projectXyz</groupId> 
        <artifactId>xyz</artifactId> 
        <version>[1.0,2.0)</version> 
        </dependency> 
        <dependency> 
        <groupId>projectFoo</groupId> 
        <artifactId>foo</artifactId> 
        <version>1</version> 
        <exclusions> 
         <exclusion> 
         <groupId>projectXyz</groupId> 
         <artifactId>xyz</artifactId> 
         </exclusion> 
        </exclusions> 
        </dependency> 
        <dependency> 
        <groupId>projectBar</groupId> 
        <artifactId>bar</artifactId> 
        <version>5</version> 
        <exclusions> 
         <exclusion> 
         <groupId>projectXyz</groupId> 
         <artifactId>xyz</artifactId> 
         </exclusion> 
        </exclusions> 
        </dependency> 
    </dependencyManagement> 
    ... 
    <!-- Declare your dependencies but don't allow them to suck in their transitive dependencies. --> 
    <dependencies> 
        <dependency> 
        <groupId>projectXyz</groupId> 
        <artifactId>xyz</artifactId> 
        </dependency> 
        <dependency> 
        <groupId>projectFoo</groupId> 
        <artifactId>foo</artifactId> 
        </dependency> 
        <dependency> 
        <groupId>projectBar</groupId> 
        <artifactId>bar</artifactId> 
        </dependency> 
    </dependencies> 
    ... 
    

    這將搭載最新的xyz.jar之能的版本,這將是唯一使用的版本。當foo和bar使用xyz時,他們將擁有允許進入項目的版本。

    要做的最好的事情是使用(或bom:物料清單)和一個定義良好且維護良好的dependencyManagement部分。堅持一切的單一版本,只是分享所有項目之間的「一切」。如果需要,您可以覆蓋項目中的版本。

    如果您希望在每個項目中定義版本,那麼version ranges將起作用。因爲你給了三個例子,你可以使用之類的東西:

    • [1.1.0,1.2)
    • [1.4.0,1.5)
    • [2.0.0)

    (打開更正這裏..我還沒有使用的版本範圍在近10年。)

    最後,爲了得到它使用的是已經上市,而不是下載最好的,你可以版本是的使用local artifact repository作爲您的中央Maven存儲庫,並使用turn off access to maven central and bintray

    +0

    我懷疑本地存儲庫選項是否解決了「版本切換」需求('1.1.0' - >'1.1.2'等),因爲Maven仍然會在本地存儲庫中查找1.1.0版本(如果我理解的話正確),如果無法找到它會失敗,而不是「決定」嘗試其他可用的版本? –

    +0

    是的,你必須保持你的版本範圍是最新的,這就是爲什麼我建議父pom/bom解決方案(從那時起,你只需要更新一個文件來修復所有項目)。如果你的依賴/依賴管理範圍是[1.1.0,1.2),那麼maven將選擇1.1.2而不是1.1.0。 –