Maven 的生命周期由阶段构成,而阶段本身不做事,插件目标绑定到阶段上才执行。这篇用一个真实的 jar 项目验证:每个阶段累加执行哪些目标、绑定顺序、直接调用目标的后果、两个跳过测试的开关以及失败时的行为。
mvn no-such-phase 的错误信息列出的合法阶段:30 个:pre-clean,clean,post-clean,validate,initialize,generate-sources,process-sources,generate-resources,process-resources,compile,process-classes,generate-test-sources,process-test-sources,generate-test-resources,process-test-resources,test-compile,process-test-classes,test,prepare-package,package,pre-integration-test,integration-test,post-integration-test,verify,install,deploy,pre-site,site,post-site,site-deploy mvn validate:rc=0,执行 0 个目标:(无) mvn compile:rc=0,执行 2 个目标:resources:resources → compiler:compile mvn test:rc=0,执行 5 个目标:resources:resources → compiler:compile → resources:testResources → compiler:testCompile → surefire:test mvn package:rc=0,执行 6 个目标:resources:resources → compiler:compile → resources:testResources → compiler:testCompile → surefire:test → jar:jar mvn verify:rc=0,执行 6 个目标:resources:resources → compiler:compile → resources:testResources → compiler:testCompile → surefire:test → jar:jar mvn install:rc=0,执行 7 个目标:resources:resources → compiler:compile → resources:testResources → compiler:testCompile → surefire:test → jar:jar → install:install
mvn compile:执行 5 个目标(含 id):resources:copy-resources[early] → resources:resources[default-resources] → resources:copy-resources[zz-first] → resources:copy-resources[aa-second] → compiler:compile[default-compile] target 下生成的目录:classes,extra0,extra1,extra2,generated-sources,maven-status
全新项目 mvn compiler:compile:rc=0,执行 1 个目标:compiler:compile;target/classes 内容:App.class;src/main/resources 的 a.txt 被复制了吗:False 全新项目 mvn jar:jar(没有先编译):rc=0,执行 1 个目标:jar:jar;jar 里的条目数 7,其中 .class 0 个;警告:JAR will be empty - no content was marked for inclusion! 先 mvn compile 再 mvn jar:jar:jar 条目数 9,其中 .class 1 个,a.txt 1 个 mvn compile surefire:test(阶段与目标混用):执行 3 个目标:resources:resources → compiler:compile → surefire:test
第一次 mvn package:6 个目标,日志 "Compiling" 行:Compiling 1 source file with javac [debug release 17]; Compiling 1 source file with javac [debug release 17]
第二次 mvn package(没有改动):6 个目标,日志:Nothing to compile - all classes are up to date.; Nothing to compile - all classes are up to date.; Tests run: 1, Failures: 0, Errors: 0, Skipped: 0;"Building jar" 日志行数:第一次 1,第二次 0(jar 没有改动时 jar 目标不再重新打包,也不打日志)
mvn package -DskipTests:6 个目标:resources:resources → compiler:compile → resources:testResources → compiler:testCompile → surefire:test → jar:jar
日志:Compiling 1 source file with javac [debug release 17] to target/classes; Compiling 1 source file with javac [debug release 17] to target/test-classes; Tests are skipped.
mvn package -Dmaven.test.skip=true:6 个目标:resources:resources → compiler:compile → resources:testResources → compiler:testCompile → surefire:test → jar:jar
日志:Not compiling test sources; Tests are skipped.
target 下是否有 test-classes:False测试失败时 mvn package:rc=1,执行 5 个目标:resources:resources → compiler:compile → resources:testResources → compiler:testCompile → surefire:test;生成 jar:False;结果:[ERROR] BUILD FAILURE 加 -Dmaven.test.failure.ignore=true:rc=0,执行 6 个目标:resources:resources → compiler:compile → resources:testResources → compiler:testCompile → surefire:test → jar:jar;生成 jar:True;Tests run: 1, Failures: 1, Errors: 0, Skipped: 0