Gerenciamento de dependências

7 min

Índice


1 — O que é uma dependência?

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 MavenCom Maven
Descarregar cada .jar à mãoDeclarar 3 linhas no pom.xml
Gerir o classpath manualmenteO Maven constrói-o automaticamente
Encontrar bibliotecas compatíveisResoluçã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.

↑ Voltar ao topo


2 — Declarar uma dependência

As dependências declaram-se no bloco <dependencies> do pom.xml. Cada dependência é uma etiqueta <dependency> com as suas coordenadas GAV.

xml
<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.

bash
# Depois de acrescentar uma dependência, dispara-se o descarregamento
mvn compile

# Ou descarregar explicitamente sem compilar
mvn dependency:resolve
ElementoPapel
<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>.

✅ Ver uma solução
xml
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.10.1</version>
</dependency>

↑ Voltar ao topo


3 — Os âmbitos (scopes)

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>.

xml
<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>
ScopeDisponível na compilaçãoDisponível nos testesDisponível na execuçãoIncluído no artefacto
compile (omissão)
test
provided❌ (fornecido pelo servidor)
runtime

Exemplos concretos:

BibliotecaScope típicoPorquê
JUnittestSó útil para executar os testes
API ServletprovidedO servidor (Tomcat) já a fornece
Controlador JDBCruntimeExigido na execução, não na compilação
GsoncompileUsado em todo o código

Pôr o JUnit em compile em vez de test é 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.

✅ Ver uma solução
xml
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.10.2</version>
    <scope>test</scope>
</dependency>

↑ Voltar ao topo


4 — Os repositórios (repositories)

O Maven descarrega as dependências a partir de repositórios (repositories). Existem três níveis:

Tipo de repositórioDescrição
Repositório localCache na sua máquina: ~/.m2/repository
Maven CentralO repositório público mundial, fonte por omissão
Repositório privadoServidor de empresa (Nexus, Artifactory) para bibliotecas internas

Para acrescentar um repositório privado, declara-se no pom.xml:

xml
<repositories>
    <repository>
        <id>nexus-entreprise</id>
        <url>https://nexus.monentreprise.com/repository/maven-public/</url>
    </repository>
</repositories>
bash
# 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)
CasoRepositório usado
Biblioteca open-source públicaMaven Central
Biblioteca caseira da empresaRepositório privado (Nexus/Artifactory)
Biblioteca já descarregadaCache 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.

↑ Voltar ao topo


5 — A resolução transitiva

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:

xml
<!-- 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:

bash
# Mostra a árvore das dependências (diretas + transitivas)
mvn dependency:tree

Saí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:compile

Quando 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).

✅ Ver uma solução
bash
mvn dependency:tree

↑ Voltar ao topo


6 — Diagnosticar e excluir

Por 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:

xml
<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:

ComandoPapel
mvn dependency:treeMostra a árvore completa das dependências
mvn dependency:analyzeDeteta dependências não usadas ou em falta
mvn dependency:resolveDescarrega todas as dependências
bash
# Localizar as dependências declaradas mas não usadas,
# e as usadas mas não declaradas
mvn dependency:analyze

Antes de excluir o que quer que seja, lance mvn dependency:tree para 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).

✅ Ver uma solução
bash
mvn dependency:analyze

↑ Voltar ao topo


7 — Quiz — Gestão das dependências

Question 1

Onde 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

💡 Ver a solução

Resposta: b) — O repositório local ~/.m2/repository serve de cache: uma biblioteca já descarregada não é descarregada de novo.


Question 2

Que scope convém ao JUnit, uma biblioteca usada apenas para os testes?

a) compile

b) runtime

c) test

d) provided

💡 Ver a solução

Resposta: c) — O scope test torna a dependência disponível só nos testes e exclui-a do entregável final.


Question 3

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

💡 Ver a solução

Resposta: b) — Uma dependência declarada traz as suas próprias dependências; o Maven descarrega-as automaticamente.


Question 4

Que comando mostra a árvore completa das dependências?

a) mvn list

b) mvn dependency:tree

c) mvn show-deps

d) mvn package

💡 Ver a solução

Resposta: b)mvn dependency:tree mostra as dependências diretas e transitivas, útil para diagnosticar conflitos.


Question 5

Que scope escolher para a API Servlet, fornecida pelo servidor Tomcat?

a) compile

b) test

c) provided

d) runtime

💡 Ver a solução

Resposta: c)provided: a biblioteca é necessária para compilar, mas o ambiente de execução (o servidor) já a fornece.

↑ Voltar ao topo


8 — Prática — Acrescentar dependências

Instrução

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.


Correção — Bloco <dependencies> esperado

xml
<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:

bash
# Descarregar e mostrar a árvore das dependências
mvn dependency:tree

Resultado 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:test

Repare que junit-jupiter traz automaticamente -api, -params e -engine: são as suas dependências transitivas. Declarou só uma linha, o Maven resolveu o resto.

↑ Voltar ao topo


9 — Síntese

Pontos a reter

  1. Uma dependência é uma biblioteca externa, identificada pelas suas coordenadas GAV.
  2. Declara-se em <dependencies>; o Maven descarrega-a e põe-na em cache em ~/.m2.
  3. Os âmbitos (compile, test, provided, runtime) controlam quando a dependência está disponível.
  4. Os repositórios: local (~/.m2), Maven Central (público), privado (Nexus/Artifactory).
  5. A resolução transitiva traz automaticamente as dependências das dependências; mvn dependency:tree permite inspecioná-la.

A continuação

Lição 04 — Ciclo de vida e fases: compreender as fases (compile, test, package, install, deploy) que orquestram a construção.

↑ Voltar ao topo


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