W3docs

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.

ScopeSul classpath di compilazioneSul classpath di testPacchettizzatoUso tipico
compile (default)Librerie normali
providedNoServlet API, fornita a runtime
runtimeNoDriver JDBC
testNoNoJUnit, 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 fresh

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

java— editable, runs on the server

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.0 si legge proprio come una riga di dipendenza.
  • Vengono dichiarate solo due dipendenze, ma il classpath risolto contiene quattro JAR — spring-core e jackson-annotations sono stati inclusi transitivamente, esattamente come fa Maven.
  • Il set seen garantisce 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 package esegue validate, compile e test prima di package e poi si ferma — eseguire una fase esegue sempre tutte le fasi precedenti in ordine.
  • La build si ferma a package e non raggiunge mai install, 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

Esercitazione

Pratica
In Maven, cosa succede quando si esegue 'mvn package'?
In Maven, cosa succede quando si esegue 'mvn package'?
Was this page helpful?