2014-05-01 45 views
2

我工作的地方使用Maven,我們有很多內部庫。我們試圖以向後兼容的方式進行更改,但有時我們的某個庫需要另一個庫的更新版本。如果最終產品最終不能吸引更新的庫版本,那麼這可能會導致問題。我的項目使用的是舊版本的依賴關係嗎?

對於每個最終產品,我們有一個dependencyManagement部分,聲明哪些版本的傳遞依賴項應該用於該項目。我們這樣做,而不是讓Maven找出使用哪個版本,因爲我們想要控制正在使用哪些版本的庫。

即使我們讓行家弄清楚應該使用庫的版本,它可能是舊的庫可以使用,這可能導致ClassNotFoundExceptions等..

是否有一個Maven插件或方式確定項目的依賴關係是否需要更新版本時,是否使用舊版本的依賴關係?

mvn dependency:tree但我們有很多依賴,我不希望有通過手的巨單看。

謝謝!

編輯

因爲我們有很多的圖書館,如果最終產品使用庫A,B和C,A和B都使用不同版本的C,C的最新版本是不始終使用。從Introduction to the Dependency Mechanism

依賴調解 - 這決定了遇到的工件的多個版本時,將使用什麼版本的依賴 的。 目前,Maven 2.0僅支持使用「最接近定義」 ,這意味着它將使用與依賴關係樹中項目最接近的版本 。您可以始終通過在項目的POM中明確聲明 版本來保證。請注意,如果 兩個依賴項版本在依賴關係樹中處於相同深度 ,直到Maven 2.0.8,則沒有定義哪一個會贏,但是因爲 Maven 2.0.9它是聲明中的順序:首先 聲明獲勝

+0

猜猜我很困惑。你有一個pom.xml,所以你可以控制你自己的依賴關係。 Maven 3具有傳遞依賴性,所以如果你使用的東西需要更新的依賴關係,它會代表你的。 – mortsahl

+1

Maven 3.x已經出現了相當長的一段時間(5年?)...你應該使用它。 – mortsahl

+0

是的,我正在使用Maven 3 –

回答

2

因爲我們幾乎總是在向後兼容的方式改變,它看起來像對我們最好的解決方案是確保所使用的依賴的最新版本。具有「需要上限依賴性」功能的Maven Enforcer插件可以完成此任務。

http://maven.apache.org/enforcer/enforcer-rules/requireUpperBoundDeps.html

這種規則需要在構建過程中的版本,每個依存性解決 ,等於或大於所有傳遞依賴更高 聲明。在構建 期間解決的每個依賴項的版本通常是在POM中指定的版本或具有最少傳遞步驟(「最接近」定義)的版本。有關Maven依賴關係解析的更多 信息,請參閱Maven站點。

下面是一個具體的例子。這將導致生成失敗:

<dependencies> 
    <dependency> 
     <groupId>org.slf4j</groupId> 
     <artifactId>slf4j-api</artifactId> 
     <version>1.4.0</version> 
    </dependency> 
    <dependency> 
     <groupId>ch.qos.logback</groupId> 
     <artifactId>logback-classic</artifactId> 
     <version>0.9.9</version> 
     <!-- Depends on org.slf4j:slf4j-api:1.5.0 --> 
    </dependency> 
    </dependencies> 

由於該項目將與SLF4J的API 1.4.0和SLF4J的API運行的logback經典0.9.9 1.4.0可能不是向前兼容與slf4j-api 1.5.0。

這是日誌消息:

Failed while enforcing RequireUpperBoundDeps. The error(s) are [ 
RequireUpperBoundDeps error for org.slf4j:slf4j-api:1.4.0 paths to dependency are: 
+-test:TestParent:1.0-SNAPSHOT 
    +-org.slf4j:slf4j-api:1.4.0 
and 
+-test:TestParent:1.0-SNAPSHOT 
    +-ch.qos.logback:logback-classic:0.9.9 
    +-org.slf4j:slf4j-api:1.5.0 
] 

我們很可能會設立這個插件中,我們可以開啓或關閉的輪廓。

+0

啊不知道這個規則。很好的發現。 – Will

1

我不知道有一個插件會按照你的要求去做。一般來說,一個更新的版本將會是你需要解決的問題,但這並不總是一個硬性規則 - 有時你會得到一個更新的版本,但是舊版本實際上是你需要的。

以我的經驗,你必須孤立地看待每個依賴性問題。

我們處理這個問題是通過使用<dependencyManagement/>部分按照你的建議,與Maven Enforcer插件與<DependencyConvergence/>規則一起的組合方式。

The dependencyConvergence rule

...要求依賴版本號收斂。如果一個項目有 兩個依賴關係,A和B,兩者都取決於相同的構件,C, 如果A取決於C 的不同版本,則C的版本取決於B,因此該規則將失敗構建。

基本上,如果在dependency tree中有相同庫的2個不同版本,那麼會失敗。

所以:

我這樣做的方式是 - 我們平時多模塊Maven項目,我嘗試在父級別的<dependencyManagement/>部分定義的公共依賴的版本 - 例如:SpringJersey等。然後在子模塊級別,根據需要定義專家<dependencyManagement/>部分。

在我們所有的勁歌我們定義Maven Enforcer插件與<dependencyConvergence/>規則配置如下:

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-enforcer-plugin</artifactId> 
    <version>1.3.1</version> 
    <executions> 
    <execution> 
     <id>enforce-versions</id> 
     <goals> 
     <goal>enforce</goal> 
     </goals> 
    </execution> 
    </executions> 
    <configuration> 
    <rules> 
     <DependencyConvergence/> 
    </rules> 
    <fail>true</fail> 
    </configuration> 
</plugin> 

然後在每一個Maven構建,如果有人添加了一個新的依賴(或者有一個新的傳遞依賴),其衝突與另一個,你的構建將失敗,你會得到一個(輕微重複)的依賴問題日誌供你處理。作爲一個終點,我沒有看到Maven Enforcer插件使用得太多,但它的負載爲really useful rules,並且有能力製作custom rules

如果它確實是一個dependency總是想的newest version,我敢肯定,你可以寫一個簡單的規則來做到這一點。

希望這有助於

請問