O que é o Maven e por que usar em projetos Java
O Apache Maven é uma ferramenta de automação de build e gerenciamento de dependências. Em vez de você baixar bibliotecas manualmente, configurar classpath “na mão” e criar scripts de compilação, o Maven padroniza a estrutura do projeto e descreve tudo em um arquivo central: o pom.xml. Com isso, você consegue:
- Baixar e versionar dependências automaticamente (e suas dependências transitivas).
- Executar fases de build padronizadas (
test,package, etc.). - Gerar artefatos como
.jarde forma reproduzível. - Manter um padrão de pastas que facilita integração com IDEs e CI.
Estrutura padrão de um projeto Maven
Um projeto Maven segue uma convenção de diretórios. A estrutura mais comum é:
meu-projeto/ pom.xml src/ main/ java/ (código fonte da aplicação) resources/ (arquivos de configuração, templates, etc.) test/ java/ (testes automatizados) resources/ (recursos usados em testes)O Maven compila automaticamente o que está em src/main/java e executa testes em src/test/java (normalmente com JUnit). Recursos em resources são copiados para o classpath do artefato final.
O papel do pom.xml
O pom.xml (Project Object Model) descreve o projeto: suas coordenadas, dependências, plugins de build e configurações. É o “contrato” que permite a qualquer pessoa (ou servidor) construir o projeto do zero com os mesmos resultados.
Coordenadas: groupId, artifactId, version
As coordenadas identificam unicamente um artefato Maven:
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
Baixar o aplicativo
groupId: geralmente o domínio invertido da organização (ex.:br.com.suaempresa).artifactId: nome do projeto/módulo (ex.:app-console).version: versão do artefato (ex.:1.0.0ou1.0.0-SNAPSHOT).
Exemplo mínimo de pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>br.com.exemplo</groupId> <artifactId>app-console</artifactId> <version>1.0.0</version></project>Repositórios Maven e como as dependências são resolvidas
Quando você declara uma dependência, o Maven procura o artefato em repositórios remotos (por padrão, o Maven Central) e armazena uma cópia local no seu computador (repositório local, tipicamente em ~/.m2/repository). Isso acelera builds futuros e permite reuso entre projetos.
Quando declarar repositórios adicionais
Na maioria dos casos, o Maven Central é suficiente. Você declara repositórios adicionais quando uma biblioteca não está no Central (por exemplo, repositórios internos da empresa). Exemplo:
<repositories> <repository> <id>repo-interno</id> <url>https://repo.suaempresa.com/maven2</url> </repository></repositories>Use com critério: adicionar muitos repositórios pode tornar o build mais lento e menos previsível.
Dependências e escopos (scope)
Dependências são bibliotecas externas que seu projeto usa. No pom.xml, você declara cada dependência com suas coordenadas. Exemplo (JUnit para testes):
<dependencies> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>5.10.2</version> <scope>test</scope> </dependency></dependencies>Principais escopos
| Scope | Quando usar | Entra no classpath de compilação? | Entra no classpath de testes? | Vai para o artefato final? |
|---|---|---|---|---|
compile (padrão) | Dependência necessária para compilar e rodar | Sim | Sim | Não “embutida” automaticamente no JAR (fica como dependência externa) |
test | Somente para testes | Não | Sim | Não |
provided | Disponível no ambiente de execução (ex.: servidor) | Sim | Sim | Não |
runtime | Necessária apenas em tempo de execução | Não | Sim | Não |
Observação importante: por padrão, o Maven gera um JAR “magro” (sem dependências dentro). Para um JAR executável com dependências embutidas (fat/uber jar), você usa plugins específicos (veremos mais adiante).
Comandos essenciais do Maven (ciclo de vida)
O Maven organiza o build em fases. Você executa fases com mvn <fase>. As mais usadas:
mvn clean: limpa o diretóriotarget/(saídas de builds anteriores).mvn test: compila e executa testes.mvn package: gera o artefato (geralmente um.jar) emtarget/.
Exemplo de fluxo típico:
mvn clean test mvn clean packageVocê também pode combinar em um único comando:
mvn clean packageIsso executa clean e, em seguida, todas as fases necessárias até package (incluindo compilação e testes).
Projeto prático: transformar um programa anterior em projeto Maven
A seguir, você vai pegar um programa simples de console (com uma classe com main) e organizá-lo como um projeto Maven, adicionando testes e empacotando um JAR.
Passo 1: criar a estrutura de pastas
Crie uma pasta para o projeto e a estrutura padrão:
app-console/ pom.xml src/ main/ java/ test/ java/Passo 2: definir o pacote e mover o código para src/main/java
Escolha um pacote (por exemplo, br.com.exemplo.app). Crie as pastas correspondentes e coloque sua classe principal lá:
app-console/src/main/java/br/com/exemplo/app/App.javaExemplo de App.java:
package br.com.exemplo.app; public class App { public static void main(String[] args) { System.out.println("Olá, Maven!"); } }Passo 3: criar o pom.xml com configurações básicas
Agora crie o pom.xml na raiz. Além das coordenadas, é uma boa prática definir a versão do Java usada na compilação. Exemplo:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>br.com.exemplo</groupId> <artifactId>app-console</artifactId> <version>1.0.0</version> <properties> <maven.compiler.release>17</maven.compiler.release> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>5.10.2</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.2.5</version> </plugin> </plugins> </build></project>O maven.compiler.release define a versão alvo do Java (compilação e bytecode). Ajuste para a versão do seu JDK.
Passo 4: adicionar uma classe de lógica testável (exemplo) e criar testes
Para testar algo de forma útil, crie uma classe simples com um método e teste com JUnit.
Crie:
app-console/src/main/java/br/com/exemplo/app/SaudacaoService.javaConteúdo:
package br.com.exemplo.app; public class SaudacaoService { public String saudar(String nome) { if (nome == null || nome.isBlank()) { return "Olá!"; } return "Olá, " + nome.trim() + "!"; } }Agora crie o teste em:
app-console/src/test/java/br/com/exemplo/app/SaudacaoServiceTest.javaConteúdo:
package br.com.exemplo.app; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; public class SaudacaoServiceTest { @Test void deveSaudarComNome() { SaudacaoService service = new SaudacaoService(); assertEquals("Olá, Ana!", service.saudar("Ana")); } @Test void deveSaudarSemNomeQuandoNuloOuVazio() { SaudacaoService service = new SaudacaoService(); assertEquals("Olá!", service.saudar(null)); assertEquals("Olá!", service.saudar(" ")); } }Se quiser usar o serviço no main, atualize o App:
package br.com.exemplo.app; public class App { public static void main(String[] args) { SaudacaoService service = new SaudacaoService(); String nome = (args.length > 0) ? args[0] : ""; System.out.println(service.saudar(nome)); } }Passo 5: executar os comandos Maven (clean, test, package)
No terminal, dentro da pasta app-console:
- Limpar saídas anteriores:
mvn clean- Rodar testes:
mvn test- Gerar o JAR:
mvn packageApós mvn package, verifique a pasta target/. Você deve ver algo como:
target/ app-console-1.0.0.jar classes/ test-classes/ surefire-reports/Como executar a aplicação empacotada
Opção A: executar via classpath (sem configurar Main-Class no manifesto)
Se você ainda não configurou o JAR como executável (com Main-Class), pode rodar assim:
java -cp target/app-console-1.0.0.jar br.com.exemplo.app.AppPassando argumento:
java -cp target/app-console-1.0.0.jar br.com.exemplo.app.App AnaOpção B: gerar um JAR executável (com Main-Class)
Para permitir java -jar ..., configure o plugin de JAR para incluir o atributo Main-Class no manifesto.
No pom.xml, dentro de <build><plugins>, adicione:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.4.2</version> <configuration> <archive> <manifest> <mainClass>br.com.exemplo.app.App</mainClass> </manifest> </archive> </configuration></plugin>Reempacote:
mvn clean packageAgora execute:
java -jar target/app-console-1.0.0.jarCom argumento:
java -jar target/app-console-1.0.0.jar AnaEntendendo o que acontece no build
mvn testcompila o código principal e o de teste, e executa os testes (relatórios emtarget/surefire-reports).mvn packagegera o artefato emtarget/. Em projetos Java padrão, isso é um JAR.- Dependências baixadas ficam no repositório local (
~/.m2/repository), evitando downloads repetidos.
Checklist rápido de problemas comuns
- Erro de versão do Java: ajuste
<maven.compiler.release>para a versão do seu JDK instalado. - Testes não rodam: confirme que os testes estão em
src/test/javae que a dependência do JUnit está comscopetest. - Classe principal não encontrada: verifique o pacote e o nome completo (
br.com.exemplo.app.App) e, se usarjava -jar, confirme a configuração domaven-jar-plugin.