Das Buildsystem Maven
https://oer-informatik.de/build-tool-maven
tl/dr; (ca. 15 min Lesezeit): Mit dem Buildtool Maven kann der Erstellungsprozess von Software automatisiert werden: Kompilieren, Testen, Packen und Veröffentlichen kann nach einem vorkonfigurietem Muster wiederholbar ablaufen. (Zuletzt geändert am 07.09.2023)
Softwareprojekte mit Java bestehen häufig nicht nur aus einzelnen Quellcodedateien, sondern aus einer Vielzahl verschachtelter Abhängigkeiten. Im Software-Erstellungsprozess müssen Code und Abhängigkeiten verwaltet, organsiert, die Applikation gebaut, getestet und veröffentlicht werden. Viele der nötigen Schritte sind automatisierbar und müssen nicht von Hand vorgenommen werden: das erledigen Build-Tools wie Ant, Gradle oder Maven automatisch. Jedes dieser Buildtools hat eigene Vorteile, derzeit sind Maven und Gradle die verbreitetsten im Java-Umfeld.
Die Build-Tools kümmern sich um den Prozess, der aus Quellcode und Abhängigkeiten Stück für Stück ein lauffähiges Programm baut, dieses testet, das auslieferbare Paket erzeugt (z.B. jar-Datei) und dieses schließlich veröffentlicht. Einige der Anwendungsfälle sind in folgendem Use-Case-Diagramm zusammengetragen:

Für die meisten dieser Schritte muss Maven nicht explizit konfiguriert werden, da das Designprinzip “Convention over Configuration” zum Zug kommt: der Standardweg ist bereits vorkonfiguriert.
Maven installieren
Auf den meisten Systemen ist Maven bereits vorhanden oder bei der Installation einer Entwicklungsumgebung mit installiert. Ob Maven bereits installiert ist (und im PATH
des jeweiligen Betriebssystems eingetragen ist) lässt sich mit dem folgenden Befehl im Terminal / in der Powershell herausfinden:
Es sollte etwa die folgende Antwort kommen:
Maven home: C:\Program Files\apache-maven-bin\apache-maven-3.8.6
Java version: 17.0.4, vendor: Oracle Corporation, runtime: C:\Program Files\Java\jdk-17.0.4
Default locale: de_DE, platform encoding: Cp1252
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"
Wenn als Antwort eine Fehlermeldung (oder eine deutlich ältere Version) kommt, lohnt ein Blick auf die Install-Anleitung von Maven. Hier wird auch erklärt, wie man überprüfen kann, ob der PATH
stimmt und ob die korrekte Java-Version gefunden wird.
Maven im Schnelldurchgang
Um einmal zu verdeutlichen, wie Maven funktioniert, setzten wir den Gesamtprozess der Softwareerstellung mit Maven über die Konsole um. Das ist etwas umständlicher als nötig: schließlich nimmt uns normalerweise die Integrierten Entwicklungsumgebungen (IDE) viel Arbeit ab. Zum Beispiel bei der Projekterzeugung.
Wir erzeugen von Hand ein neues Projekt. Der Einfachheit halber nutzen wir dazu eine Maven-Vorlage (java11-archetype
) mit dem Befehl:
Etwas übersichtlicher (aber nicht ausführbar) mit zeilenweisen Optionen:
$ mvn archetype:generate -B
-D archetypeGroupId="tech.raaf"
-D archetypeArtifactId="java11-archetype"
-D groupId="de.csbme.ifaxx"
-D artifactId="myFirstMavenProject"
Nachfolgend ist kurz erklärt, welche Optionen dieser Befehl nutzt. Wen das nicht interessiert, der möge diese Tabelle einfach überspringen (verzichtbares Wissen für gerade…):
Option | Bedeutung |
---|---|
archetype:generate |
das Goal generate in dem Maven-Plugin archetype wird aufgerufen |
-B |
Batchmode (ohne Rückfragen) |
-D |
Es werden folgende Properties übergeben (die nachfolgenden Einträge) |
archetypeGroupId= "tech.raaf" |
die genutzte Vorlage gehört zur folgenden Gruppe |
archetypeArtifactId= "java11-archetype" |
die genutzte Vorlage heißt… |
groupId= "de.csbme.ifaxx" |
die Gruppe des Projekts, kann frei gewählt werden, ist oft eine umgekehrte Domain und wird die Paket-Bezeichnung des Projekts |
artifactId= "myFirstMavenProject" |
Name der Applikation, des Produkts |
Es wird eine kurze Weile dauern bis Maven alle nötigen Dateien geladen hat. Lädt nichts und kommt ein Fehler? Dann müssen vielleicht die Proxyeinträge in der settings.xml
angepasst werden.
Am Ende wiederholt Maven nochmal die oben übergebenen Parameter und beendet mit einer Erfolgsmeldung: BUILD SUCCESS
:
[INFO] Parameter: ...
[INFO] Project created from Archetype in dir: C:\...\myFirstMavenProject
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.087 s
[INFO] Finished at: 2022-10-25T20:35:39+02:00
[INFO] ------------------------------------------------------------------------
Die Maven Ordnerstruktur
Mit einem Maven-Projekt wird auch die Ordnerstruktur angelegt. Auch wenn es hier zu Abweichungen zwischen einzelnen Projekten kommen kann, gibt es doch immer die Gemeinsamkeiten:
- im Projektverzeichnis liegt die Datei
pom.xml
, die die wesentlichen Konfigurationsdaten enthält - im Unterverzeichnis
./src
finden sich zwei spiegelbildliche Verzeichnisbäume für den Application-Sourcecode (./src/main/java
) und für die Tests (./src/test/java
) - Später wird noch ein Ordner
./target
eingerichtet, in dem die Artefakte zur Veröffentlichung gespeichert werden (Produkt und Dokumentation).

Die Konfigurationsdatei: Das Project Object Model - die pom.xml
Die zentrale Konfigurationsdatei für alle Maven-Projekte ist die pom.xml
, in der das Project Object Model beschrieben ist.
Hier finden sich alle Angaben, die bei der Projekterzeugung vorgenommen wurden (z.B. ArtifactId: <artifactId>myFirstMavenProject</artifactId>
), die zugehörige Java Version (<java.version>11</java.version>
), weitere Projekteigenschaften (<properties>...</properties>
), Abhängigkeiten (<dependencies>...</dependencies>
) und Maven-Plugins (<build><plugins>...</plugins></build>
). Bei großen Projekten werden die Dateien schnell unübersichtlich, um so wichtiger, sich mit der oben genannten Struktur vertraut zu machen (gekürzte Ausgabe der Projekt-pom.xml
):
<?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>
<name>myFirstMavenProject</name>
<artifactId>myFirstMavenProject</artifactId>
<groupId>de.csbme.ifaxx</groupId>
<version>1.0-SNAPSHOT</version>
<description>An example Java 11 project using Maven and JUnit 5.x</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<main.class>com.example.test.HelloWorld</main.class>
<java.version>11</java.version>
...
</properties>
<dependencies>
<dependency>...</dependency>
</dependencies>
<build>
<plugins>
<plugin>...</plugin>
</plugins>
</build>
</project>
Diese XML-Datei entspricht den syntaktischen Regeln der Wohlgeformtheit (well formed XML: nur ein Root-Element, alle geöffneten Tags werden in identischer Reihenfolge wieder geschlossen usw). Außerdem stellt die pom.xml
ein valides XML-Dokument dar, d.h. sie kann gegen die semantischen Regeln einer Schema-Datei validiert werden (valid XML: die Reihenfolge der Tags, Attribute, Inhalte entspricht den Festlegungen dieses Schemas http://maven.apache.org/xsd/maven-4.0.0.xsd).
In der pom.xml
müssen immer mal Änderungen vorgenommen werden (Abhängigkeiten oder Plugins ergänzt usw.), daher ist es ratsam einen Editor zur komfortablen XML-Bearbeitung zur Hand zu haben (Plugins dafür haben eigentlich alle geläufigen Editoren).
Maven Lifecycle
Maven unterscheidet drei Haupttätigkeiten, die es als Lifecycle bezeichnet:
- default: das eigentliche Erstellen und Veröffentlichen von Software
- clean: Aufräumarbeiten, um nicht mehr benötigte Dateien des Buildprozesses zu löschen
- site: erstellt eine Projektdokumentation als Website
Maven Phasen des Default-Lifecycles
Der Lifecycle default
besteht aus einer ganzen Reihe von Phasen. Die wesentlichsten Phasen sind im folgenden UML-Aktivitätsdiagramm dargestellt:

Zwischen den oben abgedruckten Hauptphasen befinden sich noch weitere. Insgesamt sind es 23 Phasen, eine Übersicht findet sich z.B. in diesem Bild.
Mit dem Befehl
wird nicht nur die jeweilige Phase ausgeführt, sondern alle Phasen einschließlich der genannten. mvn test
führt also auch validate
und compile
aus, mvn deploy
führt sämtliche Phasen aus. Sofern der Befehl nicht in dem Ordner ausgeführt wird, in dem sich die pom.xml
befindet, muss ein Pfad zur pom.xml
mit Hilfe des Arguments -f
übergeben werden (z.B.: mvn site -f .\myFirstMavenProject\pom.xml
).
Das lässt sich mit dem oben erstellten Projekt ausprobieren: Das Beispielprojekt enthält unter ./src/main/java/com/example/test/HelloWorld.java
eine ausführbare Datei, unter `./src/test/java/com/example/test/HelloWorldTest.java
einen ausführbaren Test (ohne Testfunktionalität).
Wir können die einzelnen Phasen nacheinander manuell aufrufen:
mvn validate
: Es passiert noch nicht viel. Da die Projektstruktur in Ordnung ist wirdBUILD SUCCESS
ausgegeben und die Phase beendet.[INFO] Scanning for projects... [INFO] [INFO] -----------------< de.csbme.ifaxx:myFirstMavenProject >----------------- [INFO] Building myFirstMavenProject 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.247 s [INFO] Finished at: 2022-10-26T08:15:10+02:00 [INFO] ------------------------------------------------------------------------
mvn compile
: Die Validierung wird ausgeführt, danach wird nach Klassen gesucht und diese kompiliert. Die dabei entstehenden Bytecode-Dateien (*.class
) finden sich in den jetzt neu erzeugten Ordnern unter./target/classes
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ myFirstMavenProject --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory C:\Users\hanne\testpro\myFirstMavenProject\src\main\resources [INFO] [INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ myFirstMavenProject --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 2 source files to C:\Users\hanne\testpro\myFirstMavenProject\target\classes [WARNING] system modules path not set in conjunction with -source 11
mvn test
: Wiecompile
, danach werden jedoch auch noch die Tests kompiliert (Bytecode in./target/test-classes
) und ausgeführt. Die Testergebnisse werden in der Konsole ausgegeben:[INFO] --- maven-surefire-plugin:2.22.1:test (default-test) @ myFirstMavenProject --- [INFO] [INFO] ------------------------------------------------------- [INFO] T E S T S [INFO] ------------------------------------------------------- [INFO] Running com.example.test.HelloWorldTest [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.034 s - in com.example.test.HelloWorldTest [INFO] [INFO] Results: [INFO] [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
mvn package
: Wietest
, jedoch werden die kompilierten Bytecodedateien in ein Archiv verpackt (z.B. ein ausführbares Java-ArchivJAR
- das nutzen wir i.d.R. / einWAR
: Web Application Archive, z.B. für Tomcat-Server/ oder einEAR
für JavaEE Anwendungen für JBOSS oder WebSphere). Diese Datei stellt das Artefakt dar, das später veröffentlicht wird.[INFO] --- maven-jar-plugin:3.1.1:jar (default-jar) @ myFirstMavenProject --- [INFO] Building jar: C:\Users\hanne\testpro\myFirstMavenProject\target\myFirstMavenProject-1.0-SNAPSHOT.jar
mvn integration-test
undmvn verify
: Wenn diese Phasen konfiguriert sind, dann wirdpackage
ergänzt um die hinterlegten Integrationstests. Außerdem werden weitere Kontrollen durchgeführt (z.B. Codeabdeckung usw.), die sicherstellen sollen, dass sich das Artefakt in dem geforderten Zustand befindet.mvn install
: führt alle vorigen Phasen aus und installiert das Artefakt lokal im Maven-Repository. Damit ist es als Abhängigkeit für andere Projekte verfügbar.[INFO] --- maven-install-plugin:2.4:install (default-install) @ myFirstMavenProject --- [INFO] Installing C:\Users\hanne\testpro\myFirstMavenProject\target\myFirstMavenProject-1.0-SNAPSHOT.jar to C:\Users\hanne\.m2\repository\de\csbme\ifaxx\myFirstMavenProject\1.0-SNAPSHOT\myFirstMavenProject-1.0-SNAPSHOT.jar [INFO] Installing C:\Users\hanne\testpro\myFirstMavenProject\pom.xml to C:\Users\hanne\.m2\repository\de\csbme\ifaxx\myFirstMavenProject\1.0-SNAPSHOT\myFirstMavenProject-1.0-SNAPSHOT.pom
mvn deploy
: Wenn diese Phase konfiguriert ist, wird das Artefakt in ein Remote-Repository für Artefakte übertragen. Da das in unserem Fall nicht konfiguriert ist, wirft diese Phase einen Fehler.[INFO] --- maven-deploy-plugin:2.7:deploy (default-deploy) @ myFirstMavenProject --- [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 7.266 s [INFO] Finished at: 2022-10-26T08:43:20+02:00 [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy (default-deploy) on project myFirstMavenProject: Deployment failed: repository element was not specified in the POM inside distributionManagement element or in -DaltDeploymentRepository=id::layout::url parameter -> [Help 1]
Neben diesen Hauptphasen des Default-Lifecyles (sowie der zahllosen Unterphasen, die wir hier unterschlagen haben) gab es ja noch zwei weiter Lifecyles, die wir auch kurz ausprobieren wollen:
mvn clean
: Zurück auf Start! Alle Änderungen durch Maven-Aufrufe, insbesondere im./target
-Ordner, werden rückgängig gemacht. Gegebenenfalls muss noch das Plugin in derpom.xml
-Datei ergänzt werden:mvn site
: Erstellt die Dokumentation des Projekts als HTML-Seiten im Ordner./target/site
. Gegebenenfalls muss noch das Plugin in derpom.xml
-Datei ergänzt werden:Die von Maven erstellte Dokumentation
Ausführen eines mit Maven erstellten Projekts
In Maven selbst wird das Projekt nur erstellt, ausgeführt wird das jeweilige Artefakt abhängig vom Typ. JAR-Dateien können (nachdem sie mit mvn package
gebaut wurden) i.d.R. direkt in der JVM gestartet werden über den Befehl:
Es gibt aber auch den Weg über das exec-Plugin. Dazu muss im Properties-Bereich die Starterklasse (die Klasse mit der public static void main()
- Methode) angegeben werden:
<properties>...
<exec.mainClass>com.example.test.HelloWorld</exec.mainClass>
...<properties>
Das Maven-Goal (das Plugin) ruft man dann wie folgt auf:
mvn exec:java
Da im vorhinein der Code kompiliert werden muss, erfolgt der Aufruf häufig über eine Verkettung mehrerer Lifecyle (clean/default) Phasen (compile) und Plugins/Goals.
mvn clean compile exec:java
Der Aufruf erfolgt bei ReST-Services und anderen Artefakten auf anderem Weg. Wir werden uns das zu gegebenem Zeitpunkt genauer ansehen.
Leitfragen
Was ist im Kontext von Maven ein Artefakt?
Was versteht man im Kontext von Maven unter einer Phase?
Was versteht man im Kontext von Maven unter einem Goal?
In welche wesentlichen Bereiche gliedert sich die
pom.xml
?Wie hängen die Phasen in Maven zusammen?
Links und weitere Informationen
Wer schon einen Schritt weiter ist: Eigene Artefakte auf Maven Central veröffentlichen
Hinweis zur Nachnutzung als Open Educational Resource (OER)
Dieser Artikel und seine Texte, Bilder, Grafiken, Code und sonstiger Inhalt sind - sofern nicht anders angegeben - lizenziert unter CC BY 4.0. Nennung gemäß TULLU-Regel bitte wie folgt: “Maven installieren” von H. Stein (oer-informatik.de), Lizenz: CC BY 4.0. Der Artikel wurde unter https://oer-informatik.de/build-tool-maven veröffentlicht, die Quelltexte sind in weiterverarbeitbarer Form verfügbar im Repository unter https://gitlab.com/oer-informatik/java-advanced/build-tool-maven. Stand: 07.09.2023.
[Kommentare zum Artikel lesen, schreiben] / [Artikel teilen] / [gitlab-Issue zum Artikel schreiben]