Ciclo di vita del build Maven in Java
Scopri i tre cicli di vita di Maven e le fasi principali — validate, compile, test, package, verify, install, deploy — e come i plugin si collegano ad essi.
Un ciclo di vita è l'idea centrale di Maven: costruire un progetto non è un insieme arbitrario di compiti, ma una sequenza ordinata di fasi ben note. Quando digiti mvn package, non stai nominando un'azione singola — stai chiedendo a Maven di eseguire ogni fase fino a package inclusa, in ordine. Capire questa sequenza, e come gli obiettivi dei plugin vi si collegano, è la differenza tra copiare comandi a caso e sapere davvero cosa fa il tuo build.
Tre cicli di vita, e quello che usi di più
Maven include tre cicli di vita integrati. Sono indipendenti — invocare una fase di uno non attiva gli altri.
| Ciclo di vita | Scopo | Fasi principali |
|---|---|---|
clean | Rimuovere l'output del build | pre-clean, clean, post-clean |
default | Costruire e distribuire il progetto | validate … compile … test … package … install … deploy |
site | Generare la documentazione del progetto | pre-site, site, site-deploy |
Il ciclo di vita default è dove avviene il lavoro vero. Quel mvn clean install che vedi ovunque è semplicemente due cicli di vita in un unico comando: la fase clean del ciclo clean, poi la fase install del ciclo default.
Le fasi del ciclo di vita default
Il ciclo di vita default ha 23 fasi, ma sette portano il peso di quasi ogni build. Vengono sempre eseguite in questo ordine:
| Fase | Cosa fa |
|---|---|
validate | Verifica che il progetto sia corretto e che tutte le informazioni necessarie siano disponibili |
compile | Compila il codice sorgente principale del progetto |
test | Esegue i test unitari con un framework adatto (non richiede il packaging) |
package | Raccoglie il codice compilato in un formato distribuibile, ad es. un JAR |
verify | Esegue controlli sui risultati dei test di integrazione per confermare la qualità |
install | Copia il pacchetto nel repository locale (~/.m2) per altri progetti locali |
deploy | Carica il pacchetto in un repository remoto per la condivisione |
La regola che governa tutto: eseguire una fase esegue quella fase e tutte le fasi precedenti. Quindi mvn package esegue silenziosamente validate, compile e test prima. Non c'è modo di "saltare avanti" — puoi solo fermarti prima.
mvn validate # just the sanity checks
mvn compile # validate -> compile
mvn test # validate -> compile -> test
mvn package # ... -> test -> package (produces target/app-1.0.jar)
mvn install # ... -> package -> verify -> install (now in ~/.m2)
mvn deploy # the full pipeline, ending with an uploadLe fasi sono vuote finché i plugin non vi associano obiettivi
Una fase è solo un nome e una posizione nella sequenza — non esegue alcun lavoro da sola. Il lavoro è svolto dagli obiettivi dei plugin che sono associati alle fasi. Un obiettivo si scrive come plugin:goal, ad es. compiler:compile. Per un progetto il cui <packaging> è jar, Maven fornisce un insieme sensato di associazioni predefinite:
| Fase | Obiettivo associato di default |
|---|---|
compile | maven-compiler-plugin:compile |
test | maven-surefire-plugin:test |
package | maven-jar-plugin:jar |
install | maven-install-plugin:install |
deploy | maven-deploy-plugin:deploy |
Puoi aggiungere le tue associazioni in pom.xml. Qui il plugin exec è collegato alla fase verify in modo che venga eseguito automaticamente verso la fine del build:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>smoke-test</id>
<phase>verify</phase>
<goals><goal>java</goal></goals>
</execution>
</executions>
</plugin>
</plugins>
</build>Puoi anche invocare un obiettivo direttamente, al di fuori di qualsiasi fase — mvn compiler:compile esegue solo quell'obiettivo, saltando completamente il ciclo di vita. Questo è occasionalmente utile, ma nel quotidiano chiami le fasi e lasci che le associazioni si attivino.
Un esempio pratico: simulare il ciclo di vita
Maven non è installato su questo runner, quindi modelliamo il ciclo di vita in Java puro per rendere concreti i suoi meccanismi. Il programma elenca le fasi default, registra il plugin:goal associato a ciascuna, poi "esegue" mvn install — eseguendo ogni fase da validate fino a install, e dimostrando che deploy e clean non vengono inclusi.
Cosa ricavare dall'esecuzione:
- L'output parte da
validatee si ferma ainstall— sei fasi per un solo comando. È la regola cumulativa in azione:mvn installè un'abbreviazione per eseguire l'intero prefisso della sequenza fino ainstall, non solo la singola fase nominata. - Ogni fase eseguita ha stampato il
plugin:goalad essa associato (compile -> compiler:compile,package -> jar:jar, e così via). Le fasi sono slot; gli obiettivi sono ciò che effettivamente compila, testa e impacchetta.validateha stampato(no goal bound), mostrando che una fase può essere eseguita senza fare nulla. deploy skipped : trueconferma che le fasi successive a quella richiesta non vengono mai eseguite. Per pubblicare su un repository remoto devi chiedere esplicitamentemvn deploy; un sempliceinstallrimane deliberatamente locale.clean ran : falsedimostra checleanappartiene a un ciclo di vita separato. Invocareinstallnon eliminatarget/, ed è esattamente per questo chemvn clean installli specifica entrambi — una fase da ciascun ciclo di vita.- Le fasi sono state eseguite nel seguente ordine fisso:
validate, compile, test, package, verify, install, e il programma si è concluso conBUILD SUCCESS. L'ordine non è negoziabile; la promessa di convention-over-configuration di Maven si basa su questa sequenza garantita e ripetibile.
Comandi comuni nella pratica
Un manciata di invocazioni copre quasi tutto il lavoro quotidiano:
mvn clean # delete target/
mvn test # build and run unit tests
mvn package -DskipTests # build the JAR without running tests
mvn clean install # fresh build, install to local ~/.m2
mvn clean verify # CI's favourite: build + unit + integration checks-DskipTests compila i test ma non li esegue; -Dmaven.test.skip=true salta anche la compilazione. Usa il primo quando i test sono lenti ma devono comunque compilare, il secondo solo quando vuoi davvero escluderli del tutto.
Dove andare dopo
- Nuovo allo strumento? Inizia con l'introduzione a Maven, poi leggi come il POM dichiara plugin e associazioni.
- Le fasi come
compileepackagehanno successo solo dopo che le librerie del progetto sono state risolte — vedi gestione delle dipendenze. - Preferisci un modello a grafo di attività rispetto a una sequenza di fasi fissa? Confronta con l'introduzione a Gradle.