2016-08-15 85 views
1

我有一個多模塊項目,即Maven的模塊依賴源的代替存儲庫罐子

parent 
    module1 
    module2 

在一個dev的週期,我添加了一個類mod1.A到Module。 module2中的類mod2.B取決於它。我的地方.m2/repository沒有文物。在一個錯誤的線沿線的

$ cd prj/module2 
$ mvn -o exec:java -Dexec.mainClass=mod2.B 

結果:運行此

The following artifacts could not be resolved: com.example:module1:jar:1.0-SNAPSHOT 

我通過mvn install而在prj文件夾中安裝工件後,這一切都按預期工作。

然而,這呈現在至少兩個方面的問題:

  • 我不得不通過速度較慢的安裝階段,而不是更快的編譯階段
  • 我有同樣的項目,並相互矛盾的兩個版本這些修改。我無法與他們各自的修改,只有當前已安裝的修改即可運行同一個Java類,考慮到他們都是相同的快照版本

有兩種解決方法(跳過構建的部分爲第一,不同的快照版本對於第二個),但它們在實踐中還遠遠不可用。

有沒有辦法讓maven使用本地模塊,而不是使用本地maven倉庫中的工件?

+0

從父母本身運行Maven,請參閱http://stackoverflow.com/questions/33131880/maven-multi-module-project-cannot-find-sibling-module。您可以在'parent'的POM上運行'mvn clean package',Maven將正確解析模塊間依賴關係,無需安裝任何東西。 – Tunaki

+0

謝謝@Tunaki - 適用於'mvn clean package',但看起來像'mvn exec:java'在這種情況下不起作用。也許是因爲如果有多個具有相同名稱的類,它不知道要從哪個子模塊執行exec?我也嘗試了http://stackoverflow.com/questions/11091311/maven-execjava-goal-on-a-multi-module-project,但這並沒有幫助,解決了我在問題中給出的相同人爲因素。 –

+1

是的,這很正常。您應該將執行'exec:java'目標綁定到特定階段(如'')。或者你可以建立一個單一的模塊,如下所示http://stackoverflow.com/a/3899772/1743880 – Tunaki

回答

2

如果我正確理解你的問題,看起來你在這裏生活的規範有點不合適:你有兩個不同修改的本地「副本」,你希望在運行時交替使用「 EXEC:JAVA」。而且Maven正在迎頭趕上:它期望您的本地庫存區域.m2在發揮作用,但是每個副本中的版本字符串都是相同的,因此最終會導致副本之間的更改發生干擾。

對我來說,這聽起來像你試圖做的是測試你的改變。我建議你在module2中編寫一個實際的JUnit或TestNG測試,測試你想要的(如果你想的話,它可以調用mod2.B Main)。然後,從您選擇的項目目錄中,您可以運行mvn test -Dtest=MyTestName。它不會「安裝」任何東西,它會以你想要的方式找到依賴關係。

否則,我可以看到三個選項。

  1. 在其中一個副本中本地更改版本字符串(mvn versions:set -DnewVersion=B-SNAPSHOT可以爲您執行此操作)。這樣,你的作品中的任何「已安裝」的罐子都不會被其他副本所考慮,反之亦然。你稱之爲「遠非可用」......我認爲它應該沒問題?這些是不同版本的項目!他們應該有不同的版本字符串!我強烈建議這三個選項之一。 (如果使用:set,則完成時可以執行mvn versions:revert,或者您可以依靠版本控制撤消更改。)
  2. 選擇Maven在使用命令行標誌處理其中一個項目時使用的其他本​​地存儲庫根據https://stackoverflow.com/a/7071791/58549。我並不認爲這是一個好的解決方案,因爲每次使用這兩個項目時都必須非常小心地使用正確的標誌。另外,你最終不得不重新下載Maven插件和任何其他的依賴項到你的新本地倉庫中,這是浪費時間。
  3. 儘量避免使用任何本地存儲庫在所有。你似乎試圖讓這個選項有效。我認爲這也不是一個好方法;你正在反對Maven的期望,並且它限制了你的靈活性。 Maven確實會首先從「反應堆」(即正在執行的mvn進程)中找到依賴關係,但這意味着所有必需的模塊必須在反應堆中可用才能找到,這意味着您只能在頂層運行mvn。所以,如果你想在單個模塊中執行「mvn exec:java」,mvn需要在某個地方找到該模塊的依賴關係......這就是本地回購通常用於的地方。

如果與選項3(而不是選擇1)會是死心塌地,那麼我建議你遵循你的問題的意見,並創建一個用於運行exec選擇性針對模塊2,並將其綁定到一個配置文件生命週期階段。但是這在實踐中非常接近於僅僅用測試來包裝它。

+0

感謝Zac,提供了很多有用的建議和新信息,這些信息消除了我原來的一些困難。我會通過它來查看哪一個最適合。 –

+0

爲了記錄,我認爲Maven的這方面很糟糕,我不是唯一一個認爲這種方式的人,例如http://stackoverflow.com/questions/1677473/maven-doesnt-recognize-sibling-modules-when-running-mvn-dependencytree - 查看作者發佈的各種評論 –

0

Maven中的模塊的要點是在它們之間創建解耦。您可以獨立構建每個模塊,以便您可以在不接觸其他模塊的情況下處理一個模塊,也可以將這兩個模塊作爲子模塊包含在父pom中並構建父代,這將解決其子模塊之間的依賴性並觸發其構建。

看起來你這裏有兩種選擇:

  1. 審查項目的結構。你是否真的需要將它分成兩個獨立的模塊,如果你同時改變它們兩個的代碼?
  2. 將項目導入Maven-aware IDE(IntelliJ IDEA非常善於使用Maven),並讓IDE處理編譯。一旦完成並穩定代碼庫,通常使用Maven進行構建。
+0

謝謝vempo。我主要按照你的建議來做事情,我的項目組織也不是問題。我特意詢問有關同時運行兩個不同版本的問題,而不是因爲我提到的原因而安裝到資源庫中(節省時間並使其實用)。不知道你如何回答我的主要問題,你能澄清嗎? –

+0

你的意思是你有相同版本號的同一個模塊的兩個修改? – vempo

+0

正確。請注意,當我們談論SNAPSHOT版本時,「相同版本號」並不意味着太多 - 1.0-SNAPSHOT是一個流暢版本。 –