2016-03-04 138 views
1

我有3罐,即jar1,jar2,jar3。類路徑和maven配置文件

在jar1有一些代碼讀取從類路徑的文件。但是該文件不會出現在jar1的類路徑中。相反,jar2將作爲jar1的依賴插入,並且jar2 classpath將包含該文件。

我有jar3,它也會在其classpath中包含相同的文件,但我會聲明範圍爲test jar3中的jar1的pom.xml

現在,當測試例的執行,我們怎麼能告訴Maven來總是從jar3文件(如範圍測試)的classpath雖然jar2給出主要依賴(範圍不是測試)?

基於Maven型材這可能嗎?如果是的話我們如何指定它? 或者我們可以使用maven-resources-plugin在測試範圍內複製文件嗎?

究竟是怎樣的classpath會,如果相同的文件存在於給出依賴多個罐子設置?

樣品jar1的pom.xml

<dependencies> 
     <dependency> 
      <groupId>com.test</groupId> 
      <artifactId>jar2</artifactId> 
      <version>0.1-SNAPSHOT</version> 
     </dependency> 
     <dependency> 
      <groupId>com.test</groupId> 
      <artifactId>jar3</artifactId> 
      <version>0.1-SNAPSHOT</version> 
      <scope>test</scope> 
     </dependency> 
</dependencies> 

兩個jar2和jar3具有資源文件。

問題:哪些將有所回升,爲什麼?

回答

1

如果你的依賴是在依賴關係樹同級別,申報在你的pom的訂貨會勝利,因爲每Maven Dependency Mediation DOC:

注意,如果兩個依賴的版本是在同一深度依賴關係樹,直到Maven 2.0.8它沒有定義哪一個會贏,但自從Maven 2.0.9它是在聲明中的順序計數:第一個聲明贏得

所以在你的情況下,兩個依賴在依賴關係樹(第一級,在POM中聲明)和處於同一級別範圍將(根據您發佈的剪斷)的方式存在,只要test範圍會,因爲這樣jar2會贏,因爲你在你的POM宣佈它第一。

如果您希望文件始終從jar3加載,但僅在測試期間,只需在您的依賴關係中首先聲明jar3即可。它不會影響最終的可交付成果(在test作用域中),但它將定義到類路徑的測試順序,併爲您提供預期的方案。你不需要Maven配置文件。


一個簡單的測試用例來驗證:

讓我們來定義一個屬性file.properties到Maven項目的src\main\resources。該文件看起來像項目resource-provider(的artifactId)以下:

property=from-resource-provider 

而且如下項目resource-provider2(的artifactId):

property=from-resource-provider2 

注:相同的文件名與不同的兩個不同的項目內容。

然後在消費項目(resource-consumer),我們可以有以下示例JUnit測試案例:

public class MainTest { 

    @Test 
    public void checkClassPath() { 
     InputStream is = MainTest.class.getResourceAsStream("/file.properties"); 
     Scanner s = new Scanner(is); 
     System.out.println(s.nextLine()); 
    } 

} 

對於下面的依賴關係到resource-consumer

<dependencies> 
    <dependency> 
     <groupId>com.sample</groupId> 
     <artifactId>resource-provider2</artifactId> 
     <version>0.0.1-SNAPSHOT</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>com.sample</groupId> 
     <artifactId>resource-provider</artifactId> 
     <version>0.0.1-SNAPSHOT</version> 
    </dependency> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>4.11</version> 
     <scope>test</scope> 
    </dependency> 
</dependencies> 

測試執行的輸出將是:

------------------------------------------------------- 
T E S T S 
------------------------------------------------------- 
Running com.sample.MainTest 
property=from-resource-provider2 
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.051 sec 

因此,第一個de申報失敗,resource-provider2,贏了(注意範圍,test)。

改變依賴以:

<dependencies> 
    <dependency> 
     <groupId>com.sample</groupId> 
     <artifactId>resource-provider</artifactId> 
     <version>0.0.1-SNAPSHOT</version> 
    </dependency> 
    <dependency> 
     <groupId>com.sample</groupId> 
     <artifactId>resource-provider2</artifactId> 
     <version>0.0.1-SNAPSHOT</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>4.11</version> 
     <scope>test</scope> 
    </dependency> 
</dependencies> 

反而會提供以下的輸出:

------------------------------------------------------- 
T E S T S 
------------------------------------------------------- 
Running com.sample.MainTest 
property=from-resource-provider 
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.07 sec 

注意:這個時候resource-provider韓元,因爲它被宣佈第一,因爲compile範圍也部分test的範圍,而相反的情況並非如此。

+0

..謝謝你..很明確的解釋.. –

+0

@svsteja不客氣。附註:當使用這種方法時(基於訂購),我會建議添加評論給你的POM,以幫助其他開發人員或未來的維護和故障排除:) –