實踐環境
Apache Maven 3.0.5 (Red Hat 3.0.5-17)
maven構建生命周期
學習Maven構建命令之前,我們不煩先簡單了解下Maven構建生命周期。
Maven基於構建生命周期的核心概念。構建生命周期由phase
(形如clean
,compile
, install
等)組成。每個phase
由插件目標Plugin goal
(形如sonar:sonar
)組成。也就是說,每個phase
負責構建生命周期中的特定步驟,並且通過綁定到該phase
的的插件來實現這些步驟的具體執行。
每個插件目標代表一個特定的任務(比phase
更精細),可能綁定到0個或多個構建phase
。未綁定到任何phase
的目標可以通過直接調用在構建生命周期之外執行。執行順序取決於插件目標和phase
的順序
默認的生命周期由以下phase
組成( 點擊查看完整的phase列表)
validate
- 校驗項目是否是正確,並且是否可獲取所有必要信息compile
test
package
verify
- 對集成測試結果進行檢查以確保滿足關鍵質量。install
deploy
maven構建命令
mvn [選項] [<goal(s)>] [<phase(s)>]
常用選項:
-f,--file <arg>
強制使用指定的POM文件
-U,--update-snapshots
強制檢查缺少的release
版和遠程倉庫已更新snapshots
版(Forces a check for missing releases and updated snapshots on remote repositories)。個人理解:
- 如果構建依賴的
release
版軟件包在本地倉庫不存在,則強制從遠程倉庫下載最新release
版依賴包,否則不下載,使用本地倉庫已有的release
版依賴包 - 不管構建依賴的
snapshots
版軟件包在本地倉庫是否存在,都強制檢查遠程倉庫對應版本的軟件包是否存在更新,如果存在則下載更新。
-N,--non-recursive
不遞歸到子項目(子模塊)。
說明:多個goal
、phase
之間使用空格分隔。
示例:
# mvn clean -Dautoconfig.skip=true -Dmaven.test.skip=true install
常用內置phase
介紹
clean
刪除前一次構建生成的文件,包括classes目錄中的.class文件,但不會刪除classes
, generated-sources
, maven-status
目錄。
compile
編譯項目源代碼,會生成.class文件和對應軟件包,注意:*.class
以及軟件包(比如*.jar
)不存在,或者源代碼有變動的情況下,執行編譯,才會重新生成*.class
及對應軟件包,package
,install
,deploy
等皆如此。
test
使用合適的單元測試框架(默認為Junit
)運行測試。這些測試不應要求打包或部署代碼。可使用-Dmaven.test.skip=true
、-DskipTests
參數跳過測試。這兩者的區別在於:
-DskipTests
不執行測試用例,但編譯測試用例類生成相應的.class
文件到target/test-classes
下。-Dmaven.test.skip=true
,不執行測試用例,也不編譯測試用例類。
package
獲取編譯后的代碼,並將其打包為可分發的格式,例如jar
install
將打包的軟件包安裝至本地倉庫,為本地其它項目提供依賴。實踐表名,執行install
命令,可能會生成在compile
階段未生成的軟件包。
deploy
在集成或發布環境中完成,將最終軟件包復制到遠程存倉庫,以便與其他開發人員和項目共享。
注意:
1、phase
之間,phase
和goal
之間是有順序區分的,按從左到右的順序執行,如下兩個命令,看似相同,執行效果是不一樣的。
# mvn clean install # 先執行clean,再執行install
# mvn install clean # 先執行install,再執行clean
2、maven執行某個phase
之前,會優按順序執行該phase
所屬生命周期內,位於其之前的所有phase
,比如執行默認生命周期的install
,會優先執行validate —> compile -> test -> package -> verify
(假設未使用其它會跳過phase
的選項參數)
插件目標應用舉例
sonar掃描
# mvn clean -Dautoconfig.skip=true -Dmaven.test.skip=true compile org.jacoco:jacoco-maven-plugin:prepare-agent sonar:sonar
問題:這里為啥需要用org.jacoco:jacoco-maven-plugin:prepare-agent
插件目標呢?
答案:因為僅靠SonarQube本身是不知道實際上執行了哪些測試以及它們如何覆蓋代碼的,要獲取此信息,它依賴於第三方測試覆蓋率工具,對於Java,它依賴於JaCoCo
收集和提供的數據
關於父POM構建
假設項目中包含子項目、模塊,那么構建父POM時,會按序構建所有子項目、子模塊,可以簡單理解為批量構建。
參考連接
https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-maven/