Maven — Cheat Sheet

Tag: maven, java, build-tool, pom, dependencies, packaging, lifecycle

Livello: intermedio

TL;DR: Strumento dichiarativo per build automation e gestione dipendenze in Java, basato su convenzioni standard e Project Object Model (POM).

Concetti chiave

Gestione dichiarativa delle dipendenze e del ciclo di vita del software tramite il file standard pom.xml.

Approccio Convention over Configuration per directory sorgenti (src/main/java), risorse e output compilato (target).

Identificazione univoca delle coordinate di un artefatto tramite GAV: groupId, artifactId e version.

Tre lifecycle indipendenti incorporati nel core: default (build/deploy), clean (pulizia) e site (documentazione).

Fasi sequenziali del default lifecycle: validate, compile, test, package, verify, install, deploy.

L'esecuzione di una fase attiva automaticamente tutte le fasi precedenti nello stesso lifecycle.

Ogni plugin Maven espone uno o piu goal associati a specifiche fasi del lifecycle.

Risoluzione dipendenze a cascata tra repository locale (~/.m2/repository), central repository e repository remoti aziendali.

Scope delle dipendenze per isolare classpath: compile, provided, runtime, test, system e import.

Multi-module build orchestrata tramite un POM root con packaging pom e dichiarazione <modules>.

Domande tipiche e risposte pronte

Q: Qual e la differenza fondamentale tra la fase install e la fase deploy?

R: La fase install copia l'artefatto compilato nel repository locale .m2 per l'uso su macchina, mentre deploy lo carica sul repository remoto condiviso.

Q: Come gestisci il versioning centralizzato in un progetto multi-modulo?

R: Definisco la sezione <dependencyManagement> nel POM padre per fissare versioni ed esclusioni, lasciando ai sotto-moduli solo groupId e artifactId.

Q: Che differenza c'e tra scope compile e provided?

R: compile include la dipendenza in compilazione, test e pacchetto finale; provided la usa per compilare ma delega la presenza a runtime all'ambiente target.

Q: Come risolvi un conflitto tra due versioni transitive della stessa libreria?

R: Uso <exclusions> sulla dipendenza diretta che trascina la versione indesiderata, oppure dichiaro esplicitamente la versione corretta nel POM.

Insidie e errori comuni

Usare mvn clean install indiscriminatamente allungando i tempi di build invece di eseguire solo le fasi necessarie.

Conflitti di dipendenze transitive nascoste con eccezioni tipo NoSuchMethodError o ClassNotFoundException a runtime.

Salto dei test con flag -Dmaven.test.skip=true che impedisce anche la compilazione delle classi di test (-DskipTests salta solo l'esecuzione).

Hardcoding di credenziali dei repository privati dentro il pom.xml invece che nel file ~/.m2/settings.xml.

Moduli ciclici nelle dipendenze che bloccano la costruzione del grafo di build (DAG).

Snippet e comandi

# Compilazione e packaging standard
mvn clean package

# Esecuzione build saltando solo l'esecuzione dei test
mvn clean package -DskipTests

# Installazione locale dell'artefatto
mvn clean install

# Analisi dell'albero delle dipendenze per identificare conflitti
mvn dependency:tree

# Debug dei conflitti di dipendenza filtrando per artifactId specifico
mvn dependency:tree -Dincludes=org.slf4j:*

# Ispezione del POM effettivo dopo ereditarieta e profili
mvn help:effective-pom
<!-- Configurazione tipica di dependencyManagement nel POM padre -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>3.2.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<!-- Esclusione dipendenza transitiva conflittuale -->
<dependency>
    <groupId>org.example</groupId>
    <artifactId>my-library</artifactId>
    <version>1.0.0</version>
    <exclusions>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Da ripassare

[ ] Meccanismo di risoluzione "nearest definition wins" per dipendenze transitive

[ ] Differenza tra -DskipTests e -Dmaven.test.skip=true

[ ] Utilizzo dei profili (<profiles>) e loro attivazione condizionale

[ ] Configurazione di settings.xml per repository privati Nexus/Artifactory

Modifica direttamente o con Gemini Fai clic in un punto qualsiasi per digitare e modificare direttamente oppure seleziona il testo per chiedere a Gemini di apportare modifiche.

Ho generato la cheat sheet tecnica su Maven rispettando la struttura e le regole specificate. Vuoi approfondire una sezione o passare al prossimo argomento?

Jarvis Interviews
Jarvis