Introduzione a Java Maven
Cos'è Maven, come costruisce i progetti Java e come installare ed eseguire i comandi mvn.
Maven è lo strumento standard di automazione della build e gestione delle dipendenze per Java. Trasforma un progetto in una descrizione dichiarativa — cosa è, da cosa dipende, come viene costruito — e poi esegue la build al posto tuo. Invece di gestire manualmente i file JAR e i flag javac, dichiari le tue esigenze in un singolo file e Maven scarica le dipendenze, compila, testa e pacchettizza il tuo codice attraverso un ciclo di vita prevedibile e ripetibile.
Il POM: un progetto come dati
Ogni progetto Maven è descritto da un pom.xml (Project Object Model). Identifica il progetto con tre coordinate — groupId, artifactId e version (insieme le "GAV") — e elenca le librerie di cui ha bisogno. Lo stesso schema di coordinate nomina il tuo progetto e ogni dipendenza, ed è così che Maven individua gli artefatti in un repository.
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>shop-app</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.release>21</maven.compiler.release>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>6.1.0</version>
</dependency>
</dependencies>
</project>L'elemento <packaging> indica a Maven cosa produrre (jar, war, pom). Il blocco <properties> contiene valori riutilizzabili — in questo caso, la versione Java a cui punta il compilatore. Il POM si espande per coprire plugin, profili ed ereditarietà; il capitolo Maven POM analizza quelle parti in dettaglio.
Dipendenze e il classpath transitivo
Elenchi solo le tue dipendenze dirette. Maven legge il POM di ogni dipendenza e include tutto ciò di cui esse hanno bisogno — le dipendenze transitive — costruendo automaticamente il classpath completo. Dichiarare spring-web include anche spring-core senza che tu debba nominarlo esplicitamente.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.0</version>
</dependency>Ogni dipendenza ha uno scope che controlla quando è disponibile sul classpath. Il valore predefinito, compile, la rende disponibile ovunque; test la limita al codice di test; provided significa che è il runtime a fornirla. Per i conflitti di versione, le esclusioni e dependencyManagement, consulta Maven dependencies.
| Scope | Sul classpath di compilazione | Sul classpath di test | Pacchettizzato | Uso tipico |
|---|---|---|---|---|
compile (default) | Sì | Sì | Sì | Librerie normali |
provided | Sì | Sì | No | Servlet API, fornita a runtime |
runtime | No | Sì | Sì | Driver JDBC |
test | No | Sì | No | JUnit, Mockito |
Il ciclo di vita della build
Le build di Maven percorrono una sequenza fissa di fasi. Le fasi principali del ciclo di vita predefinito sono validate, compile, test, package, verify, install e deploy. Eseguire una fase esegue tutte le fasi precedenti — mvn package prima valida, compila e testa, poi pacchettizza. Non si possono mai chiamare le fasi fuori ordine.
mvn compile # compile main sources
mvn test # compile + run unit tests
mvn package # compile + test + build the JAR/WAR
mvn install # package + copy artifact into your local repository
mvn clean package # delete target/ first, then build freshOgni fase è associata a uno o più goal forniti dai plugin (ad esempio compiler:compile è associato alla fase compile). I plugin sono dove risiede il lavoro effettivo; il ciclo di vita si limita a ordinarlo. Il capitolo Maven build lifecycle illustra tutti e tre i cicli di vita integrati e come i goal si collegano alle fasi.
Repository
Maven recupera gli artefatti dai repository. Durante una build, cerca prima nel tuo repository locale (~/.m2/repository), una cache sulla tua macchina. Se non lo trova, lo scarica da un repository remoto — di default Maven Central — e ne salva una copia localmente affinché la build successiva avvenga senza connessione. I team spesso aggiungono un repository privato per le librerie interne.
project pom.xml → local repo (~/.m2) → remote repo (Maven Central)
(cache hit?) (download + cache)Un esempio eseguibile
Il code runner non ha Maven nel suo classpath, quindi il programma seguente modella le meccaniche fondamentali di Maven con codice JDK puro: memorizza un piccolo POM come mappa, risolve la chiusura transitiva delle dipendenze (eliminando i duplicati degli artefatti condivisi) e percorre il ciclo di vita della build, fermandosi alla fase richiesta. Le strutture qui — coordinate GAV, risoluzione transitiva, fasi ordinate — sono esattamente ciò che fa il vero Maven.
Cosa osservare dall'esecuzione:
- Il progetto e ogni dipendenza sono identificati dallo stesso triplo GAV, ed è per questo che
Project coordinates: com.example:shop-app:1.0.0si legge proprio come una riga di dipendenza. - Vengono dichiarate solo due dipendenze, ma il classpath risolto contiene quattro JAR —
spring-coreejackson-annotationssono stati inclusi transitivamente, esattamente come fa Maven. - Il set
seengarantisce che ogni artefatto compaia una sola volta; questa è la deduplicazione di Maven che impedisce a una libreria condivisa di finire due volte sul classpath. Executing: mvn packageeseguevalidate,compileetestprima dipackagee poi si ferma — eseguire una fase esegue sempre tutte le fasi precedenti in ordine.- La build si ferma a
packagee non raggiunge maiinstall, rispecchiando come il goal richiesto limita fino a dove avanza il ciclo di vita.
Quando usare Maven
Maven eccelle sui progetti Java e JVM convenzionali: le sue impostazioni predefinite "convention over configuration" (sorgenti in src/main/java, test in src/test/java, output in target/) fanno sì che un nuovo collaboratore possa compilare qualsiasi progetto Maven nello stesso modo. Il suo XML dichiarativo è facile da leggere e confrontare, e il supporto IDE è maturo. Il compromesso è la verbosità e la flessibilità limitata per build non standard. Dove si necessita di build scriptate e altamente personalizzate, Gradle è l'alternativa comune — utilizza uno script di build programmabile invece di XML dichiarativo, ma copre lo stesso terreno: coordinate GAV, dipendenze transitive e un grafo di task (invece di fasi).
Prossimi passi
- Maven POM — la struttura completa di
pom.xml, inclusi plugin ed ereditarietà. - Maven dependencies — scope, esclusioni e risoluzione dei conflitti di versione in profondità.
- Maven build lifecycle — ogni fase, i tre cicli di vita e il binding dei goal.
- Introduzione a Gradle — l'alternativa basata su script a Maven.