Ciclo de Vida de Build do Java Maven
Aprenda os três ciclos de vida do Maven e as fases padrão — validate, compile, test, package, verify, install, deploy — e como os goals de plugins se vinculam a eles.
Um ciclo de vida é a ideia central do Maven: construir um projeto não é um conjunto arbitrário de tarefas, mas uma sequência ordenada de fases bem conhecidas. Quando você digita mvn package, não está nomeando uma única ação — está pedindo ao Maven para executar todas as fases até package (inclusive), em ordem. Entender essa sequência e como os goals de plugins se vinculam a ela é a diferença entre copiar comandos às cegas e realmente saber o que seu build faz.
Três ciclos de vida, e o que você mais usa
O Maven vem com três ciclos de vida integrados. Eles são independentes — invocar uma fase de um não aciona outro.
| Ciclo de vida | Propósito | Fases principais |
|---|---|---|
clean | Remover a saída do build | pre-clean, clean, post-clean |
default | Construir e implantar o projeto | validate … compile … test … package … install … deploy |
site | Gerar a documentação do projeto | pre-site, site, site-deploy |
O ciclo de vida default é onde o trabalho de verdade acontece. Aquele mvn clean install que você vê em todo lugar é simplesmente dois ciclos de vida em um único comando: a fase clean do ciclo de vida clean, seguida da fase install do ciclo de vida default.
As fases do ciclo de vida default
O ciclo de vida default tem 23 fases, mas sete carregam o peso de quase todo build. Elas sempre são executadas nesta ordem:
| Fase | O que faz |
|---|---|
validate | Verifica se o projeto está correto e se todas as informações necessárias estão disponíveis |
compile | Compila o código-fonte principal do projeto |
test | Executa testes unitários com um framework adequado (não requer empacotamento) |
package | Empacota o código compilado em um formato distribuível, por ex., um JAR |
verify | Executa verificações nos resultados de testes de integração para confirmar a qualidade |
install | Copia o pacote no repositório local (~/.m2) para outros projetos locais |
deploy | Envia o pacote para um repositório remoto para compartilhamento |
A regra que governa tudo: executar uma fase executa essa fase e todas as fases anteriores. Portanto, mvn package executa silenciosamente validate, compile e test primeiro. Não há como "pular à frente" — você só pode parar mais cedo.
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 uploadFases ficam vazias até que plugins vinculem goals a elas
Uma fase é apenas um nome e uma posição na sequência — ela não faz nada por si só. O trabalho é feito pelos goals de plugins que são vinculados às fases. Um goal é escrito como plugin:goal, por ex., compiler:compile. Para um projeto cujo <packaging> é jar, o Maven fornece um conjunto padrão sensato de vinculações:
| Fase | Goal vinculado por padrão |
|---|---|
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 |
Você pode adicionar suas próprias vinculações no pom.xml. Aqui, o plugin exec é conectado à fase verify para que seja executado automaticamente perto do final do 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>Você também pode invocar um goal diretamente, fora de qualquer fase — mvn compiler:compile executa apenas aquele goal, ignorando o ciclo de vida completamente. Isso é ocasionalmente útil, mas no dia a dia você chama fases e deixa as vinculações dispararem.
Um exemplo prático: simulando o ciclo de vida
O Maven em si não está instalado neste ambiente, então modelamos o ciclo de vida em Java puro para tornar suas regras concretas. O programa lista as fases padrão, registra o plugin:goal vinculado a cada uma e depois "executa" mvn install — executando todas as fases de validate até install, e provando que deploy e clean não são incluídos.
O que tirar da execução:
- A saída começa em
validatee para eminstall— seis fases para um único comando. Essa é a regra cumulativa em ação:mvn installé uma abreviação para executar todo o prefixo da sequência atéinstall, nunca apenas a fase nomeada isoladamente. - Cada fase executada imprimiu o
plugin:goalvinculado a ela (compile -> compiler:compile,package -> jar:jar, e assim por diante). Fases são slots; os goals são o que realmente compila, testa e empacota.validateimprimiu(no goal bound), mostrando que uma fase pode ser executada sem fazer nada. deploy skipped : trueconfirma que as fases após a que você solicita nunca são executadas. Para publicar em um repositório remoto, você precisa pedir explicitamentemvn deploy; um simplesinstalldeliberadamente fica local.clean ran : falseprova quecleanpertence a um ciclo de vida separado. Invocarinstallnão excluitarget/, razão exata pela qualmvn clean installespecifica os dois — uma fase de cada ciclo de vida.- As fases foram executadas na ordem fixa
validate, compile, test, package, verify, installe o programa terminou comBUILD SUCCESS. A ordenação não é negociável; a promessa de convenção-sobre-configuração do Maven depende dessa sequência garantida e repetível.
Comandos comuns na prática
Um punhado de invocações cobre quase todo o trabalho diário:
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 os testes mas não os executa; -Dmaven.test.skip=true pula a compilação deles também. Use o primeiro quando os testes são lentos mas ainda devem ser compilados, o segundo somente quando você realmente quer que eles fiquem fora do caminho.
Para onde ir a seguir
- Novo na ferramenta? Comece com a introdução ao Maven, depois leia como o POM declara plugins e vinculações.
- Fases como
compileepackagesó têm sucesso depois que as bibliotecas do projeto são resolvidas — veja gerenciando dependências. - Prefere um modelo de grafo de tarefas em vez de uma sequência de fases fixa? Compare com a introdução ao Gradle.