Apache Maven Tutorial

1. Einleitung

Das Erstellen eines Softwareprojekts besteht normalerweise aus Aufgaben wie dem Herunterladen von Abhängigkeiten, dem Platzieren zusätzlicher Jars in einem Klassenpfad, dem Kompilieren von Quellcode in Binärcode, dem Ausführen von Tests, dem Packen von kompiliertem Code in bereitstellbare Artefakte wie JAR-, WAR- und ZIP-Dateien und dem Bereitstellen dieser Artefakte zu einem Anwendungsserver oder Repository.

Apache Maven automatisiert diese Aufgaben, minimiert das Risiko, dass Menschen Fehler machen, während die Software manuell erstellt wird, und trennt die Arbeit des Kompilierens und Packens unseres Codes von der der Codekonstruktion.

In diesem Tutorial werden wir dieses leistungsstarke Tool zum Beschreiben, Erstellen und Verwalten von Java-Softwareprojekten anhand einer zentralen Information - dem Project Object Model (POM) - untersuchen, die in XML geschrieben ist.

2. Warum Maven verwenden?

Die Hauptmerkmale von Maven sind:

  • Einfache Projekteinrichtung, die den Best Practices folgt: Maven versucht, so viele Konfigurationen wie möglich zu vermeiden, indem er Projektvorlagen (benannte Archetypen ) bereitstellt.
  • Abhängigkeitsmanagement: Es umfasst das automatische Aktualisieren, Herunterladen und Überprüfen der Kompatibilität sowie das Melden der Abhängigkeitsabschlüsse (auch als transitive Abhängigkeiten bezeichnet).
  • Isolation zwischen Projektabhängigkeiten und Plugins: Mit Maven werden Projektabhängigkeiten aus den Abhängigkeitsrepositorys abgerufen, während die Abhängigkeiten eines Plugins aus den Plugin-Repositorys abgerufen werden. Dies führt zu weniger Konflikten, wenn Plugins zusätzliche Abhängigkeiten herunterladen
  • Zentrales Repository-System: Projektabhängigkeiten können aus dem lokalen Dateisystem oder aus öffentlichen Repositorys wie Maven Central geladen werden
In diesem Tutorial zu Baeldung erfahren Sie, wie Sie Maven auf Ihrem System installieren.

3. Projektobjektmodell

Die Konfiguration eines Maven-Projekts erfolgt über ein Projektobjektmodell (POM) , das durch eine pom.xml- Datei dargestellt wird. Das POM beschreibt das Projekt, verwaltet Abhängigkeiten und konfiguriert Plugins zum Erstellen der Software.

Das POM definiert auch die Beziehungen zwischen Modulen von Projekten mit mehreren Modulen. Schauen wir uns die Grundstruktur einer typischen POM- Datei an:

 4.0.0 org.baeldung org.baeldung jar 1.0-SNAPSHOT org.baeldung //maven.apache.org   junit junit 4.12 test      //...    

Schauen wir uns diese Konstrukte genauer an.

3.1. Projektkennungen

Maven verwendet eine Reihe von Bezeichnern, auch Koordinaten genannt, um ein Projekt eindeutig zu identifizieren und anzugeben, wie das Projektartefakt verpackt werden soll:

  • groupId - Ein eindeutiger Basisname des Unternehmens oder der Gruppe, die das Projekt erstellt hat
  • Artefakt-ID - ein eindeutiger Name des Projekts
  • version - eine Version des Projekts
  • Verpackung - eine Verpackungsmethode (zB WAR / JAR / ZIP )

Die ersten drei davon ( groupId: artefaktId: version ) bilden zusammen die eindeutige Kennung und sind der Mechanismus, mit dem Sie angeben, welche Versionen externer Bibliotheken (z. B. JARs) Ihr Projekt verwenden soll.

3.2. Abhängigkeiten

Diese externen Bibliotheken, die ein Projekt verwendet, werden als Abhängigkeiten bezeichnet. Die Abhängigkeitsverwaltungsfunktion in Maven gewährleistet das automatische Herunterladen dieser Bibliotheken aus einem zentralen Repository, sodass Sie sie nicht lokal speichern müssen.

Dies ist eine wichtige Funktion von Maven und bietet die folgenden Vorteile:

  • verbraucht weniger Speicherplatz, da die Anzahl der Downloads von Remote-Repositorys erheblich reduziert wird
  • beschleunigt das Auschecken eines Projekts
  • bietet eine effektive Plattform für den Austausch von binären Artefakten innerhalb Ihres Unternehmens und darüber hinaus, ohne dass jedes Mal Artefakte aus dem Quellcode erstellt werden müssen

Um eine Abhängigkeit von einer externen Bibliothek zu deklarieren, müssen Sie die Gruppen-ID, die Artefakt-ID und die Version der Bibliothek angeben . Schauen wir uns ein Beispiel an:

 org.springframework spring-core 4.3.5.RELEASE 

Während Maven die Abhängigkeiten verarbeitet, wird die Spring Core-Bibliothek in Ihr lokales Maven-Repository heruntergeladen.

3.3. Repositories

Ein Repository in Maven wird verwendet, um Build-Artefakte und Abhängigkeiten unterschiedlicher Typen zu speichern. Das lokale Standard-Repository befindet sich im Ordner .m2 / repository unter dem Ausgangsverzeichnis des Benutzers.

Wenn ein Artefakt oder ein Plug-In im lokalen Repository verfügbar ist, verwendet Maven es. Andernfalls wird es aus einem zentralen Repository heruntergeladen und im lokalen Repository gespeichert. Das zentrale Standard-Repository ist Maven Central.

Einige Bibliotheken, wie z. B. der JBoss-Server, sind nicht im zentralen Repository verfügbar, sondern in einem alternativen Repository. Für diese Bibliotheken müssen Sie die URL zum alternativen Repository in der Datei pom.xml angeben :

  JBoss repository //repository.jboss.org/nexus/content/groups/public/  

Bitte beachten Sie, dass Sie in Ihren Projekten mehrere Repositorys verwenden können.

3.4. Eigenschaften

Benutzerdefinierte Eigenschaften können dazu beitragen, dass Ihre pom.xml- Datei leichter zu lesen und zu warten ist. Im klassischen Anwendungsfall würden Sie benutzerdefinierte Eigenschaften verwenden, um Versionen für die Abhängigkeiten Ihres Projekts zu definieren.

Maven-Eigenschaften sind Wertplatzhalter und können überall in einer pom.xml mit der Notation $ {name} aufgerufen werden , wobei name die Eigenschaft ist.

Sehen wir uns ein Beispiel an:

 4.3.5.RELEASE    org.springframework spring-core ${spring.version}   org.springframework spring-context ${spring.version}  

Wenn Sie Spring auf eine neuere Version aktualisieren möchten, müssen Sie nur den Wert innerhalb von ändernEigenschaftstag und alle Abhängigkeiten, die diese Eigenschaft in ihrem verwenden Tags werden aktualisiert.

Eigenschaften werden auch häufig verwendet, um Build-Pfadvariablen zu definieren:

 ${project.build.directory}/tmp/   //... ${project.resources.build.folder} //... 

3.5. Bauen

The build section is also a very important section of the Maven POM. It provides information about the default Maven goal, the directory for the compiled project, and the final name of the application. The default build section looks like this:

 install ${basedir}/target ${artifactId}-${version}  filters/filter1.properties  //... 

The default output folder for compiled artifacts is named target, and the final name of the packaged artifact consists of the artifactId and version, but you can change it at any time.

3.6. Using Profiles

Another important feature of Maven is its support for profiles. A profile is basically a set of configuration values. By using profiles, you can customize the build for different environments such as Production/Test/Development:

  production    //...      development  true     //...     

As you can see in the example above, the default profile is set to development. If you want to run the production profile, you can use the following Maven command:

mvn clean install -Pproduction

4. Maven Build Lifecycles

Every Maven build follows a specified lifecycle. You can execute several build lifecyclegoals, including the ones to compile the project’s code, create a package, and install the archive file in the local Maven dependency repository.

4.1. Lifecycle Phases

The following list shows the most important Maven lifecycle phases:

  • validate – checks the correctness of the project
  • compile – compiles the provided source code into binary artifacts
  • test – executes unit tests
  • package – packages compiled code into an archive file
  • integration-test – executes additional tests, which require the packaging
  • verify – checks if the package is valid
  • install – installs the package file into the local Maven repository
  • deploy – deploys the package file to a remote server or repository

4.2. Plugins and Goals

A Maven plugin is a collection of one or more goals. Goals are executed in phases, which helps to determine the order in which the goals are executed.

The rich list of plugins that are officially supported by Maven is available here. There is also an interesting article how to build an executable JAR on Baeldung using various plugins.

To gain a better understanding of which goals are run in which phases by default, take a look at the default Maven lifecycle bindings.

To go through any one of the above phases, we just have to call one command:

mvn 

For example, mvn clean install will remove the previously created jar/war/zip files and compiled classes (clean) and execute all the phases necessary to install new archive (install).

Please note that goals provided by plugins can be associated with different phases of the lifecycle.

5. Your First Maven Project

In this section, we will use the command line functionality of Maven to create a Java project.

5.1. Generating a Simple Java Project

In order to build a simple Java project, let's run the following command:

mvn archetype:generate -DgroupId=org.baeldung -DartifactId=org.baeldung.java -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

The groupId is a parameter indicating the group or individual that created a project, which is often a reversed company domain name. The artifactId is the base package name used in the project, and we use the standard archetype.

Since we didn't specify the version and the packaging type, these will be set to default values — the version will be set to 1.0-SNAPSHOT, and the packaging will be set to jar.

If you don't know which parameters to provide, you can always specify interactiveMode=true, so that Maven asks for all the required parameters.

After the command completes, we have a Java project containing an App.java class, which is just a simple “Hello World” program, in the src/main/java folder.

We also have an example test class in src/test/java. The pom.xml of this project will look similar to this:

 4.0.0 org.baeldung org.baeldung.java jar 1.0-SNAPSHOT org.baeldung.java //maven.apache.org   junit junit 4.1.2 test   

As you can see, the junit dependency is provided by default.

5.2. Compiling and Packaging a Project

The next step is to compile the project:

mvn compile

Maven will run through all lifecycle phases needed by the compile phase to build the project's sources. If you want to run only the test phase, you can use:

mvn test

Now let's invoke the package phase, which will produce the compiled archive jar file:

mvn package

5.3. Executing an Application

Finally, we are going to execute our Java project with the exec-maven-plugin. Let's configure the necessary plugins in the pom.xml:

 src   maven-compiler-plugin 3.6.1  1.8 1.8    org.codehaus.mojo exec-maven-plugin 1.5.0  org.baeldung.java.App    

The first plugin, maven-compiler-plugin, is responsible for compiling the source code using Java version 1.8. The exec-maven-plugin searches for the mainClass in our project.

To execute the application, we run the following command:

mvn exec:java

6. Multi-Module Projects

The mechanism in Maven that handles multi-module projects (also called aggregator projects) is called Reactor.

The Reactor collects all available modules to build, then sorts projects into the correct build order, and finally, builds them one by one.

Let's see how to create a multi-module parent project.

6.1. Create Parent Project

First of all, we need to create a parent project. In order to create a new project with the name parent-project, we use the following command:

mvn archetype:generate -DgroupId=org.baeldung -DartifactId=parent-project

Next, we update the packaging type inside the pom.xml file to indicate that this is a parent module:

pom

6.2. Create Submodule Projects

In the next step, we create submodule projects from the directory of parent-project:

cd parent-project mvn archetype:generate -DgroupId=org.baeldung -DartifactId=core mvn archetype:generate -DgroupId=org.baeldung -DartifactId=service mvn archetype:generate -DgroupId=org.baeldung -DartifactId=webapp

To verify if we created the submodules correctly, we look in the parent-project pom.xml file, where we should see three modules:

 core service webapp 

Moreover, a parent section will be added in each submodule’s pom.xml:

 org.baeldung parent-project 1.0-SNAPSHOT 

6.3. Enable Dependency Management in Parent Project

Dependency management is a mechanism for centralizing the dependency information for a muti-module parent project and its children.

When you have a set of projects or modules that inherit a common parent, you can put all the required information about the dependencies in the common pom.xml file. This will simplify the references to the artifacts in the child POMs.

Let's take a look at a sample parent's pom.xml:

   org.springframework spring-core 4.3.5.RELEASE  //...  

By declaring the spring-core version in the parent, all submodules that depend on spring-core can declare the dependency using only the groupId and artifactId, and the version will be inherited:

  org.springframework spring-core  //... 

Moreover, you can provide exclusions for dependency management in parent's pom.xml, so that specific libraries will not be inherited by child modules:

  org.springframework spring-context  

Finally, if a child module needs to use a different version of a managed dependency, you can override the managed version in child's pom.xml file:

 org.springframework spring-core 4.2.1.RELEASE 

Please note that while child modules inherit from their parent project, a parent project does not necessarily have any modules that it aggregates. On the other hand, a parent project may also aggregate projects that do not inherit from it.

For more information on inheritance and aggregation please refer to this documentation.

6.4. Updating the Submodules and Building a Project

We can change the packaging type of each submodule. For example, let's change the packaging of the webapp module to WAR by updating the pom.xml file:

war

Now we can test the build of our project by using the mvn clean install command. The output of the Maven logs should be similar to this:

[INFO] Scanning for projects... [INFO] Reactor build order: [INFO] parent-project [INFO] core [INFO] service [INFO] webapp //............. [INFO] ----------------------------------------- [INFO] Reactor Summary: [INFO] ----------------------------------------- [INFO] parent-project .................. SUCCESS [2.041s] [INFO] core ............................ SUCCESS [4.802s] [INFO] service ......................... SUCCESS [3.065s] [INFO] webapp .......................... SUCCESS [6.125s] [INFO] -----------------------------------------

7. Conclusion

In diesem Artikel haben wir einige der beliebtesten Funktionen des Apache Maven-Build-Tools erläutert.

Alle Codebeispiele in Baeldung wurden mit Maven erstellt, sodass Sie auf unserer GitHub-Projektwebsite problemlos verschiedene Maven-Konfigurationen anzeigen können.