Uma dependência é uma biblioteca externa de que o seu projeto precisa para compilar ou executar. Em vez de reescrever código (análise JSON, acesso a base de dados, testes…), reutilizam-se bibliotecas comprovadas.
O Maven gere estas dependências automaticamente: declara-as no pom.xml e o Maven descarrega-as e coloca-as no classpath.
| Sem Maven | Com Maven |
|---|---|
Descarregar cada .jar à mão | Declarar 3 linhas no pom.xml |
| Gerir o classpath manualmente | O Maven constrói-o automaticamente |
| Encontrar bibliotecas compatíveis | Resolução transitiva automática |
Uma dependência também é identificada pelas suas coordenadas GAV (
groupId:artifactId:version), exatamente como o seu próprio projeto. É assim que o Maven sabe o que descarregar.
As dependências declaram-se no bloco <dependencies> do pom.xml. Cada dependência é uma etiqueta <dependency> com as suas coordenadas GAV.
<dependencies>
<!-- Biblioteca Gson da Google para manipular JSON -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
</dependencies>Para encontrar as coordenadas corretas de uma biblioteca, consulta-se o Maven Central (search.maven.org), que fornece o bloco XML pronto a copiar.
# Depois de acrescentar uma dependência, dispara-se o descarregamento
mvn compile
# Ou descarregar explicitamente sem compilar
mvn dependency:resolve| Elemento | Papel |
|---|---|
<groupId> | A organização que publica a biblioteca |
<artifactId> | O nome da biblioteca |
<version> | A versão desejada |
O Maven põe as bibliotecas em cache em
~/.m2/repository. Uma biblioteca já descarregada nunca é descarregada de novo: é por isso que os builds seguintes são rápidos.
🔧 Mini-exercício — Declare a dependência Gson (com.google.code.gson:gson:2.10.1) num bloco <dependency>.
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>O âmbito (scope) de uma dependência indica quando e onde está disponível: na compilação, nos testes, na execução, ou fornecida pelo ambiente. Precisa-se com <scope>.
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.2</version>
<scope>test</scope> <!-- disponível apenas para os testes -->
</dependency>| Scope | Disponível na compilação | Disponível nos testes | Disponível na execução | Incluído no artefacto |
|---|---|---|---|---|
compile (omissão) | ✅ | ✅ | ✅ | ✅ |
test | ❌ | ✅ | ❌ | ❌ |
provided | ✅ | ✅ | ❌ (fornecido pelo servidor) | ❌ |
runtime | ❌ | ✅ | ✅ | ✅ |
Exemplos concretos:
| Biblioteca | Scope típico | Porquê |
|---|---|---|
| JUnit | test | Só útil para executar os testes |
| API Servlet | provided | O servidor (Tomcat) já a fornece |
| Controlador JDBC | runtime | Exigido na execução, não na compilação |
| Gson | compile | Usado em todo o código |
Pôr o JUnit em
compileem vez detesté um erro frequente: embarca inutilmente a biblioteca de teste no entregável final. Escolha sempre o scope mais restritivo que convém.
🔧 Mini-exercício — Declare uma dependência JUnit Jupiter (5.10.2) em âmbito test no pom.xml.
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>O Maven descarrega as dependências a partir de repositórios (repositories). Existem três níveis:
| Tipo de repositório | Descrição |
|---|---|
| Repositório local | Cache na sua máquina: ~/.m2/repository |
| Maven Central | O repositório público mundial, fonte por omissão |
| Repositório privado | Servidor de empresa (Nexus, Artifactory) para bibliotecas internas |
Para acrescentar um repositório privado, declara-se no pom.xml:
<repositories>
<repository>
<id>nexus-entreprise</id>
<url>https://nexus.monentreprise.com/repository/maven-public/</url>
</repository>
</repositories># Forçar a atualização das dependências a partir dos repositórios
mvn clean install -U
# Esvaziar o cache de uma biblioteca para forçar o novo descarregamento
# (eliminação manual da pasta correspondente em ~/.m2)| Caso | Repositório usado |
|---|---|
| Biblioteca open-source pública | Maven Central |
| Biblioteca caseira da empresa | Repositório privado (Nexus/Artifactory) |
| Biblioteca já descarregada | Cache local ~/.m2 |
As empresas usam muitas vezes um repositório privado como espelho do Maven Central: isto acelera os descarregamentos e permite controlar quais bibliotecas são autorizadas.
Uma dependência pode ela própria depender de outras bibliotecas: são as dependências transitivas. O Maven descarrega-as automaticamente — não tem de as listar.
Declara uma dependência, o Maven resolve dezenas:
<!-- Uma só declaração... -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.2.5</version>
</dependency>
<!-- ...traz automaticamente spring-web, jackson, tomcat, etc. -->Para visualizar a árvore completa:
# Mostra a árvore das dependências (diretas + transitivas)
mvn dependency:treeSaída típica:
com.exemple:mon-app:jar:1.0.0
+- org.springframework.boot:spring-boot-starter-web:jar:3.2.5:compile
| +- org.springframework:spring-web:jar:6.1.6:compile
| +- com.fasterxml.jackson.core:jackson-databind:jar:2.15.4:compile
| \- org.apache.tomcat.embed:tomcat-embed-core:jar:10.1.20:compileQuando dois caminhos trazem duas versões diferentes da mesma biblioteca, o Maven aplica a regra do « mais próximo na árvore » (nearest wins): a versão mais próxima do seu projeto vence.
A resolução transitiva é uma das maiores forças do Maven: declara as suas intenções de alto nível e o Maven monta todo o puzzle das dependências por si.
🔧 Mini-exercício — Escreva o comando que mostra a árvore completa das dependências (diretas e transitivas).
mvn dependency:treePor vezes, uma dependência transitiva causa problemas (conflito de versão, biblioteca indesejada). O Maven oferece ferramentas para diagnosticar e corrigir.
Para excluir uma dependência transitiva indesejada:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.2.5</version>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>Comandos de diagnóstico úteis:
| Comando | Papel |
|---|---|
mvn dependency:tree | Mostra a árvore completa das dependências |
mvn dependency:analyze | Deteta dependências não usadas ou em falta |
mvn dependency:resolve | Descarrega todas as dependências |
# Localizar as dependências declaradas mas não usadas,
# e as usadas mas não declaradas
mvn dependency:analyzeAntes de excluir o que quer que seja, lance
mvn dependency:treepara compreender de onde vem a dependência problemática. Nunca se exclui às cegas.
🔧 Mini-exercício — Escreva o comando que localiza as dependências declaradas mas não usadas (e o inverso).
mvn dependency:analyzeOnde o Maven põe em cache as dependências descarregadas?
a) Em target/
b) Em ~/.m2/repository
c) Em src/main/resources
d) No servidor web
✅ Resposta: b) — O repositório local ~/.m2/repository serve de cache: uma biblioteca já descarregada não é descarregada de novo.
Que scope convém ao JUnit, uma biblioteca usada apenas para os testes?
a) compile
b) runtime
c) test
d) provided
✅ Resposta: c) — O scope test torna a dependência disponível só nos testes e exclui-a do entregável final.
O que são as dependências transitivas?
a) Dependências que se deve listar à mão
b) As dependências das suas dependências, resolvidas automaticamente pelo Maven
c) Dependências temporárias
d) Dependências de teste
✅ Resposta: b) — Uma dependência declarada traz as suas próprias dependências; o Maven descarrega-as automaticamente.
Que comando mostra a árvore completa das dependências?
a) mvn list
b) mvn dependency:tree
c) mvn show-deps
d) mvn package
✅ Resposta: b) — mvn dependency:tree mostra as dependências diretas e transitivas, útil para diagnosticar conflitos.
Que scope escolher para a API Servlet, fornecida pelo servidor Tomcat?
a) compile
b) test
c) provided
d) runtime
✅ Resposta: c) — provided: a biblioteca é necessária para compilar, mas o ambiente de execução (o servidor) já a fornece.
Num projeto existente, acrescente duas dependências: Gson (com.google.code.gson:gson:2.10.1) em âmbito compile para manipular JSON, e JUnit Jupiter (org.junit.jupiter:junit-jupiter:5.10.2) em âmbito test. Depois verifique a árvore das dependências.
<dependencies> esperado<dependencies>
<!-- Gson: usada em todo o código (scope compile por omissão) -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
<!-- JUnit: testes apenas -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
</dependencies>Verificação:
# Descarregar e mostrar a árvore das dependências
mvn dependency:treeResultado esperado:
com.exemple:mon-app:jar:1.0.0-SNAPSHOT
+- com.google.code.gson:gson:jar:2.10.1:compile
\- org.junit.jupiter:junit-jupiter:jar:5.10.2:test
+- org.junit.jupiter:junit-jupiter-api:jar:5.10.2:test
+- org.junit.jupiter:junit-jupiter-params:jar:5.10.2:test
\- org.junit.jupiter:junit-jupiter-engine:jar:5.10.2:testRepare que
junit-jupitertraz automaticamente-api,-paramse-engine: são as suas dependências transitivas. Declarou só uma linha, o Maven resolveu o resto.
<dependencies>; o Maven descarrega-a e põe-na em cache em ~/.m2.compile, test, provided, runtime) controlam quando a dependência está disponível.~/.m2), Maven Central (público), privado (Nexus/Artifactory).mvn dependency:tree permite inspecioná-la.Lição 04 — Ciclo de vida e fases: compreender as fases (compile, test, package, install, deploy) que orquestram a construção.
Todos os direitos reservados. Qualquer reprodução, difusão, utilização ou adaptação deste curso, no todo ou em parte, é estritamente proibida sem a autorização escrita prévia do Dr. Haythem REHOUMA.
Curso criado por Dr. Haythem REHOUMA — Desenvolvimento e implementação de soluções de dados