3.1 Maven Übersicht
Bei Maven handelt es sich um ein Build-Tool, das vor allem für Java-Projekte eingesetzt wird (aber nicht auf Java beschränkt ist).
Maven basiert auf einem Lifecycle-Konzept. Es gibt drei Lifecycles mit mehreren Phasen. Bei einem Maven-Aufruf wird ein (oder mehrere) Ziel/Ziele angegeben. Maven arbeitet dann den entsprechenden Lifecycle bis einschließlich des angegebenen Ziels ab.
Der clean Lifecycle dient der Bereinigung des Projekts und besteht aus folgenden Phasen:
Ziel | Beschreibung |
---|---|
pre-clean | Führt Aufgaben aus, die vor der eigentlichen Bereinigung notwendig sind. |
clean | Löscht alle durch vorherige Builds erzeugten Dateien. |
post-clean | Schließt die Bereinigung ab. |
Der site Lifecycle dient der Erstellung von Webseiten und besteht aus den folgenden Phasen:
Ziel | Beschreibung |
---|---|
pre-site | Führt Aufgaben aus, die vor der eigentlichen Site-Generierung notwendig sind. |
site | Generiert die Site. |
post-site | Finalisiert die Site-Generierung. |
site-deploy | Veröffentlicht die Site auf einem Webserver. |
Der Maven Build-Lifecycle besteht aus mehreren Phasen, die in einer festgelegten Reihenfolge durchlaufen werden. Jede Phase kann spezifische Plugins aktivieren, die bestimmte Aktionen ausführen. Jede Phase muss erfolgreich abgeschlossen werden, bevor die nächste ausgeführt wird. Alternativ kann eine Phase direkt angesprungen werden, z. B. mit mvn install
, was alle Phasen bis einschließlich install
durchläuft.
Ziel | Beschreibung |
---|---|
validate | Überprüft, ob das Projekt korrekt definiert ist. |
initialize | Initialisiert den Build (setzt Properties, legt Verzeichnisse an). |
generate-sources | Generiert Quellcode, der mitkompiliert wird. |
process-sources | Verarbeitet Quellcode, z. B. durch Filterung. |
generate-resources | Generiert Ressourcen für das Projekt. |
process-resources | Kopiert/verarbeitet Ressourcen ins Zielverzeichnis. |
compile | Kompiliert den Quellcode. |
process-classes | Verarbeitet kompilierte Klassen (z. B. Bytecode-Manipulation). |
generate-test-sources | Generiert Test-Quellcode. |
process-test-sources | Verarbeitet Test-Quellcode. |
generate-test-resources | Generiert Ressourcen für Tests. |
process-test-resources | Kopiert/verarbeitet Test-Ressourcen. |
test-compile | Kompiliert den Test-Quellcode. |
process-test-classes | Verarbeitet kompilierte Test-Klassen. |
test | Führt Unit-Tests aus (optional). |
prepare-package | Vorbereitung der Paketierung. |
package | Erstellt das Paket (z. B. JAR-Datei). |
pre-integration-test | Vorbereitung für Integrationstests. |
integration-test | Führt Integrationstests aus. |
post-integration-test | Bereinigt nach den Integrationstests. |
verify | Überprüft die Paketintegrität. |
install | Installiert das Paket im lokalen Repository. |
deploy | Veröffentlicht das Paket in einem Remote-Repository. |
mvn clean package
Dabei wird zuerst der clean Lifecycle bis einschließlich clean durchlaufen. Danach wird der build Lifecycle bis einschließlich package ausgeführt.
Der Maven Wrapper ermöglicht es, eine definierte Maven-Version projektspezifisch zu verwenden – unabhängig von der lokal installierten Version.
- Reproduzierbarkeit: Konsistente Ergebnisse unabhängig von der Umgebung.
- Konsistenz: Alle Entwickler nutzen dieselbe Maven-Version.
- Einfachheit: Kein manuelles Setup nötig.
Ausführung im Projektverzeichnis:
mvn wrapper:wrapper
Falls das Plugin nicht verfügbar ist, muss es in die pom.xml aufgenommen werden:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-wrapper-plugin</artifactId>
<version>3.1.1</version>
</plugin>
Nach der Installation kann Maven über ./mvnw (Unix/Mac) bzw. mvnw.cmd (Windows) gestartet werden. Die heruntergeladene Version wird in ~/.m2/wrapper gespeichert.
Ein Maven-Projekt wird eindeutig identifiziert durch:
Kennzeichnet den Ersteller/Verantwortlichen (z.B. org.jadv). Empfohlen ist ein umgedrehter Domainname.
Der Projektname, innerhalb der groupId eindeutig (z.B. jadventure).
Bezeichnet die Projektversion, z.B. 1.0.0-SNAPSHOT. SNAPSHOT-Versionen kennzeichnen Zwischenstände in der Entwicklung und sollten nicht in öffentliche Repositories geladen werden.
Ein Maven-Projekt wird in der Datei pom.xml beschrieben.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.jadv</groupId>
<artifactId>jadventure</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
Ein Projekt kann ein übergeordnetes Projekt (parent) angeben:
<parent>
<artifactId>artefact</artifactId>
<groupId>group</groupId>
<version>version</version>
</parent>
Wird kein Parent angegeben, greift Maven automatisch auf das Super-POM zurück.
Ein Maven-Projekt kann aus mehreren Modulen bestehen. Diese Struktur wird häufig in größeren Projekten verwendet, um den Code in logisch getrennte Einheiten aufzuteilen.
Sobald ein Projekt Module enthält, darf es selbst keine Artefakte wie JARs erzeugen. Stattdessen dient es ausschließlich der Konfiguration und Koordination der Module. Daher muss in der pom.xml
des Hauptprojekts folgendes Element gesetzt sein:
<packaging>pom</packaging>
Module werden im <modules>
-Block angegeben. Für jedes Modul muss ein entsprechendes Unterverzeichnis existieren, das wiederum eine eigene pom.xml
enthält. Die Module können (müssen aber nicht) das Hauptprojekt als parent
angeben.
Beispiel:
<packaging>pom</packaging>
<modules>
<module>someDir</module>
<module>otherDir</module>
</modules>
Maven erwartet in diesem Fall die Unterverzeichnisse someDir
und otherDir
, jeweils mit einer pom.xml
.
Abhängigkeiten werden im <dependencies>
-Block definiert. Jede Abhängigkeit wird über groupId
, artifactId
und version
angegeben. Maven lädt die Abhängigkeit sowie alle transitiven Abhängigkeiten automatisch.
Das Element <dependencyManagement>
dient der zentralen Verwaltung von Versionen und Konfigurationen. Es macht Abhängigkeiten verfügbar, ohne sie sofort einzubinden. In untergeordneten Projekten können diese dann referenziert werden, ohne Versionen erneut anzugeben.
Beispiel – im Parent-Projekt:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.19.0</version>
</dependency>
</dependencies>
</dependencyManagement>
Im Modul reicht dann:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</dependency>
Ein bekanntes Beispiel für dieses Vorgehen ist Spring Boot. Dort wird durch das spring-boot-starter-parent
die Versionierung zentral übernommen. Im eigenen Projekt müssen für die meisten Abhängigkeiten keine Versionen mehr angegeben werden – das vermeidet Versionskonflikte und erhöht die Wartbarkeit.
Im <build>
-Block wird der Buildprozess über Plugins definiert. Maven selbst führt keine Tasks aus, sondern delegiert alle Aufgaben an Plugins.
Zusätzlich zum regulären <plugins>
-Block gibt es auch <pluginManagement>
. Dort können Plugins samt Version und Konfiguration definiert werden, ohne sie sofort zu aktivieren. In Modulen oder Unterprojekten kann das Plugin dann ohne erneute Konfiguration eingebunden werden.