Enterprise Maven POM Beispielbuch

Ziel: Dieses Markdown-Buch zeigt mehrere fiktive, aber realistische Enterprise-Maven-Projekte.
Es ist für Lernen, Dokumentation, Workshops und als Vorlage für eigene Projekte gedacht.

Stand: 2026-07-02
Hinweis: Die verwendeten Versionen sind Beispielwerte. In echten Unternehmensprojekten sollten sie mit eurer Plattform-, Security- und Architekturvorgabe abgeglichen werden.


Inhaltsverzeichnis

  1. Maven-Grundlagen für Enterprise-Projekte
  2. Projekt A: Enterprise Multi-Module Spring Boot Service
  3. Projekt B: Unternehmens-BOM und Shared Libraries
  4. Projekt C: Legacy Jakarta EE WAR mit Application Server
  5. Projekt D: Batch- und Integration-Job mit Datenbankmigration
  6. Projekt E: Build-Quality-Gate Parent für Enterprise-Projekte
  7. Plugin-Erklärungen
  8. Dependency-Management-Erklärungen
  9. Build-Kommandos und typische Maven-Abläufe
  10. Checkliste für eigene Enterprise-POMs
  11. Visualisierungen: Enterprise-POMs besser verstehen

1. Maven-Grundlagen für Enterprise-Projekte

1.1 Was ist eine pom.xml?

Die pom.xml ist die zentrale Maven-Konfiguration eines Projekts. Sie beschreibt:

  • Projektkoordinaten: groupId, artifactId, version
  • Packaging: jar, war, pom
  • Dependencies
  • Dependency Management
  • Plugins
  • Plugin Management
  • Build-Konfiguration
  • Module
  • Profiles
  • Repositories
  • Deployment-Ziele

In Enterprise-Projekten ist die POM nicht nur eine Build-Datei, sondern ein technisches Steuerungsdokument.


1.2 Parent-POM, Aggregator-POM und BOM

Parent-POM

Eine Parent-POM vererbt gemeinsame Konfigurationen an Child-Projekte.

Typische Inhalte:

  • Properties
  • Dependency Management
  • Plugin Management
  • Reporting
  • Firmenweite Konventionen

Aggregator-POM

Eine Aggregator-POM enthält modules und baut mehrere Module gemeinsam.

<modules>
    <module>domain</module>
    <module>application</module>
    <module>infrastructure</module>
</modules>

BOM

Eine BOM steht für Bill of Materials. Sie verwaltet Dependency-Versionen zentral.

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.acme.platform</groupId>
            <artifactId>acme-platform-bom</artifactId>
            <version>${acme.platform.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Wichtig: Eine BOM fügt keine Dependencies automatisch hinzu. Sie definiert nur Versionen.


1.3 dependencies vs. dependencyManagement

dependencyManagement

Hier werden Versionen zentral definiert.

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

dependencies

Hier werden Dependencies tatsächlich in ein Modul eingebunden.

<dependencies>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
    </dependency>
</dependencies>

Das Modul braucht keine Version, wenn diese im Parent oder in einer importierten BOM verwaltet wird.


1.4 plugins vs. pluginManagement

pluginManagement

Definiert Plugin-Versionen und Standardkonfigurationen zentral.

<pluginManagement>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven.compiler.plugin.version}</version>
        </plugin>
    </plugins>
</pluginManagement>

plugins

Aktiviert Plugins wirklich im Build.

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
    </plugin>
</plugins>

Merksatz:

pluginManagement verwaltet. plugins führt aus.


1.5 Maven-Lifecycle

Wichtige Phasen:

Phase Bedeutung
validate Projektstruktur und Konfiguration prüfen
compile Produktivcode kompilieren
test Unit Tests ausführen
package Artefakt erstellen, z. B. JAR oder WAR
verify Integrationstests und Qualitätsprüfungen ausführen
install Artefakt ins lokale Maven Repository installieren
deploy Artefakt in ein Remote Repository veröffentlichen

Beispiel:

mvn clean verify

Dieser Befehl löscht alte Build-Ergebnisse und führt den Build bis zur Phase verify aus.


2. Projekt A: Enterprise Multi-Module Spring Boot Service

2.1 Szenario

Dieses Beispiel beschreibt einen modernen Enterprise-Service mit mehreren Maven-Modulen.

Fachliches Beispiel:

Ein Unternehmen betreibt einen Order-Service, der Bestellungen entgegennimmt, validiert, persistiert und Events veröffentlicht.

Architekturstil:

  • Clean Architecture / Hexagonal Architecture
  • Spring Boot
  • REST API
  • Datenbankzugriff
  • Messaging
  • Integrationstests
  • zentrale Parent-POM

2.2 Projektstruktur

acme-order-service/
├── pom.xml
├── order-domain/
│   └── pom.xml
├── order-application/
│   └── pom.xml
├── order-infrastructure/
│   └── pom.xml
├── order-web/
│   └── pom.xml
└── order-integration-tests/
    └── pom.xml

Modulrollen

Modul Aufgabe
order-domain Fachmodell, Value Objects, Domain Services
order-application Use Cases, Ports, Transaktionen
order-infrastructure Adapter für Datenbank, Messaging, externe Systeme
order-web REST Controller, Spring Boot Application
order-integration-tests End-to-End- und Integrationstests

2.3 Root-POM: acme-order-service/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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.acme.order</groupId>
    <artifactId>acme-order-service</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <name>ACME Order Service</name>
    <description>Enterprise Multi-Module Order Service</description>

    <modules>
        <module>order-domain</module>
        <module>order-application</module>
        <module>order-infrastructure</module>
        <module>order-web</module>
        <module>order-integration-tests</module>
    </modules>

    <properties>
        <java.version>21</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

        <spring.boot.version>4.1.0</spring.boot.version>
        <junit.version>5.13.4</junit.version>
        <testcontainers.version>1.21.3</testcontainers.version>

        <maven.compiler.plugin.version>4.0.0-beta-3</maven.compiler.plugin.version>
        <maven.surefire.plugin.version>3.5.4</maven.surefire.plugin.version>
        <maven.failsafe.plugin.version>3.5.4</maven.failsafe.plugin.version>
        <maven.enforcer.plugin.version>3.6.2</maven.enforcer.plugin.version>
        <jacoco.plugin.version>0.8.13</jacoco.plugin.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring.boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.junit</groupId>
                <artifactId>junit-bom</artifactId>
                <version>${junit.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.testcontainers</groupId>
                <artifactId>testcontainers-bom</artifactId>
                <version>${testcontainers.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>${maven.compiler.plugin.version}</version>
                    <configuration>
                        <release>${java.version}</release>
                    </configuration>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>${maven.surefire.plugin.version}</version>
                    <configuration>
                        <useModulePath>false</useModulePath>
                    </configuration>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-failsafe-plugin</artifactId>
                    <version>${maven.failsafe.plugin.version}</version>
                    <executions>
                        <execution>
                            <goals>
                                <goal>integration-test</goal>
                                <goal>verify</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-enforcer-plugin</artifactId>
                    <version>${maven.enforcer.plugin.version}</version>
                    <executions>
                        <execution>
                            <id>enforce-build-rules</id>
                            <goals>
                                <goal>enforce</goal>
                            </goals>
                            <configuration>
                                <rules>
                                    <requireMavenVersion>
                                        <version>[3.9.0,)</version>
                                    </requireMavenVersion>
                                    <requireJavaVersion>
                                        <version>[21,)</version>
                                    </requireJavaVersion>
                                    <dependencyConvergence />
                                </rules>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>

                <plugin>
                    <groupId>org.jacoco</groupId>
                    <artifactId>jacoco-maven-plugin</artifactId>
                    <version>${jacoco.plugin.version}</version>
                    <executions>
                        <execution>
                            <id>prepare-agent</id>
                            <goals>
                                <goal>prepare-agent</goal>
                            </goals>
                        </execution>
                        <execution>
                            <id>report</id>
                            <phase>verify</phase>
                            <goals>
                                <goal>report</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-enforcer-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <id>ci</id>
            <properties>
                <skip.integration.tests>false</skip.integration.tests>
            </properties>
        </profile>

        <profile>
            <id>local</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <skip.integration.tests>true</skip.integration.tests>
            </properties>
        </profile>
    </profiles>
</project>

2.4 Erklärung der Root-POM

packaging=pom

Die Root-POM erzeugt kein JAR. Sie aggregiert Module und definiert gemeinsame Konfiguration.

modules

Die Module werden gemeinsam gebaut. Maven ermittelt die Reihenfolge anhand der Modulabhängigkeiten.

properties

Versionen und Encoding werden zentral definiert. Dadurch muss man sie später nur an einer Stelle ändern.

dependencyManagement

Die Spring-Boot-, JUnit- und Testcontainers-BOMs verwalten Versionen. Child-Module können Dependencies ohne Version verwenden.

pluginManagement

Plugin-Versionen und Standardkonfigurationen werden zentral verwaltet.

plugins

Der Enforcer und JaCoCo werden auf Root-Ebene aktiviert.

profiles

  • local: lokale Entwicklung, Integrationstests optional deaktiviert
  • ci: CI-Build, Integrationstests aktiv

2.5 Domain-Modul: order-domain/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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.acme.order</groupId>
        <artifactId>acme-order-service</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <artifactId>order-domain</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

Erklärung

Das Domain-Modul bleibt absichtlich schlank.

Es enthält keine Spring-Boot-Starter, keine Datenbanktreiber und keine Web-Technologien. Dadurch bleibt die Fachlogik unabhängig von technischen Frameworks.


2.6 Application-Modul: order-application/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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.acme.order</groupId>
        <artifactId>acme-order-service</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <artifactId>order-application</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>com.acme.order</groupId>
            <artifactId>order-domain</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

Erklärung

Dieses Modul enthält Use Cases und Ports. Es darf das Domain-Modul kennen, aber nicht die technische Infrastruktur.

Beispielhafte Klassen:

CreateOrderUseCase
CancelOrderUseCase
OrderRepositoryPort
OrderEventPublisherPort

2.7 Infrastructure-Modul: order-infrastructure/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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.acme.order</groupId>
        <artifactId>acme-order-service</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <artifactId>order-infrastructure</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>com.acme.order</groupId>
            <artifactId>order-application</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
        </dependency>
    </dependencies>
</project>

Erklärung

Das Infrastructure-Modul implementiert technische Adapter:

  • JPA Repository Adapter
  • RabbitMQ Event Publisher
  • Flyway Datenbankmigrationen
  • externe Client-Implementierungen

Die Abhängigkeit zeigt bewusst nach innen: Infrastruktur kennt Application, Application kennt Domain.


2.8 Web-Modul: order-web/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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.acme.order</groupId>
        <artifactId>acme-order-service</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <artifactId>order-web</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>com.acme.order</groupId>
            <artifactId>order-application</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>com.acme.order</groupId>
            <artifactId>order-infrastructure</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring.boot.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Erklärung

Dieses Modul enthält die startbare Anwendung.

Das Spring Boot Maven Plugin erzeugt ein ausführbares Artefakt. In Enterprise-Umgebungen wird dieses JAR häufig als Container Image, Kubernetes Deployment oder VM-Service ausgeliefert.


2.9 Integration-Test-Modul: order-integration-tests/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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.acme.order</groupId>
        <artifactId>acme-order-service</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <artifactId>order-integration-tests</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>com.acme.order</groupId>
            <artifactId>order-web</artifactId>
            <version>${project.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>junit-jupiter</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>postgresql</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <configuration>
                    <skipITs>${skip.integration.tests}</skipITs>
                    <includes>
                        <include>**/*IT.java</include>
                    </includes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Erklärung

Dieses Modul trennt Integrationstests von Unit Tests. Dateien mit Namen wie OrderApiIT.java werden über Failsafe ausgeführt.

Enterprise-Vorteil:

  • Unit Tests bleiben schnell.
  • Integrationstests laufen in CI zuverlässig mit echten Services via Testcontainers.
  • Build-Fehler werden in der Phase verify sichtbar.

2.10 Typische Builds für Projekt A

Lokaler schneller Build

mvn clean install -Plocal

CI-Build mit Integrationstests

mvn clean verify -Pci

Nur ein Modul und benötigte Abhängigkeiten bauen

mvn clean verify -pl order-web -am

-pl wählt ein Projekt aus.
-am baut benötigte Module mit.


3. Projekt B: Unternehmens-BOM und Shared Libraries

3.1 Szenario

Ein Unternehmen möchte Versionen, technische Standards und interne Libraries zentral verwalten.

Dieses Beispiel trennt:

  • BOM für Dependency-Versionen
  • Parent-POM für Build-Konventionen
  • Shared Libraries für wiederverwendbare technische Komponenten

3.2 Projektstruktur

acme-platform/
├── pom.xml
├── acme-platform-bom/
│   └── pom.xml
├── acme-build-parent/
│   └── pom.xml
├── acme-logging-starter/
│   └── pom.xml
├── acme-security-starter/
│   └── pom.xml
└── acme-test-support/
    └── pom.xml

3.3 Root-POM: acme-platform/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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.acme.platform</groupId>
    <artifactId>acme-platform</artifactId>
    <version>2026.07.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <module>acme-platform-bom</module>
        <module>acme-build-parent</module>
        <module>acme-logging-starter</module>
        <module>acme-security-starter</module>
        <module>acme-test-support</module>
    </modules>
</project>

3.4 BOM: acme-platform-bom/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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.acme.platform</groupId>
        <artifactId>acme-platform</artifactId>
        <version>2026.07.0-SNAPSHOT</version>
    </parent>

    <artifactId>acme-platform-bom</artifactId>
    <packaging>pom</packaging>

    <properties>
        <spring.boot.version>4.1.0</spring.boot.version>
        <jackson.version>2.20.0</jackson.version>
        <logstash.encoder.version>8.1</logstash.encoder.version>
        <testcontainers.version>1.21.3</testcontainers.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring.boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>com.fasterxml.jackson</groupId>
                <artifactId>jackson-bom</artifactId>
                <version>${jackson.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.testcontainers</groupId>
                <artifactId>testcontainers-bom</artifactId>
                <version>${testcontainers.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>net.logstash.logback</groupId>
                <artifactId>logstash-logback-encoder</artifactId>
                <version>${logstash.encoder.version}</version>
            </dependency>

            <dependency>
                <groupId>com.acme.platform</groupId>
                <artifactId>acme-logging-starter</artifactId>
                <version>${project.version}</version>
            </dependency>

            <dependency>
                <groupId>com.acme.platform</groupId>
                <artifactId>acme-security-starter</artifactId>
                <version>${project.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

Erklärung

Diese BOM wird von fachlichen Services importiert.

Beispiel in einem Service:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.acme.platform</groupId>
            <artifactId>acme-platform-bom</artifactId>
            <version>2026.07.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Vorteil: Services definieren keine eigenen Versionen für Standardbibliotheken.


3.5 Build-Parent: acme-build-parent/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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.acme.platform</groupId>
        <artifactId>acme-platform</artifactId>
        <version>2026.07.0-SNAPSHOT</version>
    </parent>

    <artifactId>acme-build-parent</artifactId>
    <packaging>pom</packaging>

    <properties>
        <java.version>21</java.version>
        <maven.compiler.plugin.version>4.0.0-beta-3</maven.compiler.plugin.version>
        <maven.enforcer.plugin.version>3.6.2</maven.enforcer.plugin.version>
        <maven.surefire.plugin.version>3.5.4</maven.surefire.plugin.version>
        <maven.failsafe.plugin.version>3.5.4</maven.failsafe.plugin.version>
        <flatten.maven.plugin.version>1.7.3</flatten.maven.plugin.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.acme.platform</groupId>
                <artifactId>acme-platform-bom</artifactId>
                <version>${project.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>${maven.compiler.plugin.version}</version>
                    <configuration>
                        <release>${java.version}</release>
                    </configuration>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>${maven.surefire.plugin.version}</version>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-failsafe-plugin</artifactId>
                    <version>${maven.failsafe.plugin.version}</version>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-enforcer-plugin</artifactId>
                    <version>${maven.enforcer.plugin.version}</version>
                    <executions>
                        <execution>
                            <id>enterprise-rules</id>
                            <goals>
                                <goal>enforce</goal>
                            </goals>
                            <configuration>
                                <rules>
                                    <requireJavaVersion>
                                        <version>[21,)</version>
                                    </requireJavaVersion>
                                    <requireMavenVersion>
                                        <version>[3.9.0,)</version>
                                    </requireMavenVersion>
                                    <banDuplicatePomDependencyVersions />
                                    <dependencyConvergence />
                                </rules>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>

                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>flatten-maven-plugin</artifactId>
                    <version>${flatten.maven.plugin.version}</version>
                    <configuration>
                        <flattenMode>resolveCiFriendliesOnly</flattenMode>
                    </configuration>
                    <executions>
                        <execution>
                            <id>flatten</id>
                            <phase>process-resources</phase>
                            <goals>
                                <goal>flatten</goal>
                            </goals>
                        </execution>
                        <execution>
                            <id>flatten-clean</id>
                            <phase>clean</phase>
                            <goals>
                                <goal>clean</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-enforcer-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>flatten-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Erklärung

Der Build-Parent ist kein normales Produktivmodul. Er dient als Firmenstandard.

Services können ihn als Parent verwenden:

<parent>
    <groupId>com.acme.platform</groupId>
    <artifactId>acme-build-parent</artifactId>
    <version>2026.07.0</version>
</parent>

Dadurch gelten automatisch:

  • Java-Version
  • Maven-Version
  • Plugin-Versionen
  • Enforcer-Regeln
  • zentrale Dependency-Versionen

3.6 Logging Starter: acme-logging-starter/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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.acme.platform</groupId>
        <artifactId>acme-build-parent</artifactId>
        <version>2026.07.0-SNAPSHOT</version>
        <relativePath>../acme-build-parent/pom.xml</relativePath>
    </parent>

    <artifactId>acme-logging-starter</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </dependency>

        <dependency>
            <groupId>net.logstash.logback</groupId>
            <artifactId>logstash-logback-encoder</artifactId>
        </dependency>
    </dependencies>
</project>

Erklärung

Dieses Modul bündelt Logging-Konventionen.

Typische Inhalte:

  • JSON Logging
  • Correlation ID
  • MDC-Konfiguration
  • Standard-Logback-Konfiguration
  • Maskierung sensibler Daten

3.7 Security Starter: acme-security-starter/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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.acme.platform</groupId>
        <artifactId>acme-build-parent</artifactId>
        <version>2026.07.0-SNAPSHOT</version>
        <relativePath>../acme-build-parent/pom.xml</relativePath>
    </parent>

    <artifactId>acme-security-starter</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
        </dependency>
    </dependencies>
</project>

Erklärung

Dieses Modul bündelt Security-Standards:

  • OAuth2 Resource Server
  • JWT Validierung
  • Security Filter Chain
  • Rollen- und Claim-Mapping
  • Standard-Fehlerantworten

4. Projekt C: Legacy Jakarta EE WAR mit Application Server

4.1 Szenario

Viele Unternehmen betreiben noch WAR-basierte Anwendungen auf Application Servern.

Dieses Beispiel zeigt:

  • packaging=war
  • provided Dependencies
  • Ressourcenfilterung
  • separate Profile für lokale und Server-Deployments
  • Integration von generiertem Code

4.2 Projektstruktur

acme-legacy-customer-portal/
├── pom.xml
├── customer-portal-web/
│   └── pom.xml
├── customer-portal-service/
│   └── pom.xml
└── customer-portal-client-generated/
    └── pom.xml

4.3 Root-POM

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.acme.customer</groupId>
    <artifactId>acme-legacy-customer-portal</artifactId>
    <version>5.4.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <properties>
        <java.version>17</java.version>
        <jakarta.ee.version>10.0.0</jakarta.ee.version>
        <maven.compiler.plugin.version>4.0.0-beta-3</maven.compiler.plugin.version>
        <maven.war.plugin.version>3.4.0</maven.war.plugin.version>
        <build.helper.plugin.version>3.6.1</build.helper.plugin.version>
    </properties>

    <modules>
        <module>customer-portal-client-generated</module>
        <module>customer-portal-service</module>
        <module>customer-portal-web</module>
    </modules>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>jakarta.platform</groupId>
                <artifactId>jakarta.jakartaee-api</artifactId>
                <version>${jakarta.ee.version}</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>${maven.compiler.plugin.version}</version>
                    <configuration>
                        <release>${java.version}</release>
                    </configuration>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>${maven.war.plugin.version}</version>
                </plugin>

                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>build-helper-maven-plugin</artifactId>
                    <version>${build.helper.plugin.version}</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

4.4 Generiertes Client-Modul

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.acme.customer</groupId>
        <artifactId>acme-legacy-customer-portal</artifactId>
        <version>5.4.0-SNAPSHOT</version>
    </parent>

    <artifactId>customer-portal-client-generated</artifactId>
    <packaging>jar</packaging>

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>add-generated-sources</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>add-source</goal>
                        </goals>
                        <configuration>
                            <sources>
                                <source>${project.build.directory}/generated-sources/wsdl</source>
                            </sources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Erklärung

Dieses Modul ist für generierten Code vorgesehen, z. B. aus WSDL, XSD oder OpenAPI.

Warum ein eigenes Modul?

  • generierter Code ist sauber getrennt
  • weniger Vermischung mit Fachlogik
  • einfacheres Caching im Build
  • klare Verantwortung

4.5 Service-Modul

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.acme.customer</groupId>
        <artifactId>acme-legacy-customer-portal</artifactId>
        <version>5.4.0-SNAPSHOT</version>
    </parent>

    <artifactId>customer-portal-service</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>com.acme.customer</groupId>
            <artifactId>customer-portal-client-generated</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>jakarta.platform</groupId>
            <artifactId>jakarta.jakartaee-api</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

4.6 WAR-Modul

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.acme.customer</groupId>
        <artifactId>acme-legacy-customer-portal</artifactId>
        <version>5.4.0-SNAPSHOT</version>
    </parent>

    <artifactId>customer-portal-web</artifactId>
    <packaging>war</packaging>

    <dependencies>
        <dependency>
            <groupId>com.acme.customer</groupId>
            <artifactId>customer-portal-service</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>jakarta.platform</groupId>
            <artifactId>jakarta.jakartaee-api</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>customer-portal</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                    <webResources>
                        <resource>
                            <directory>src/main/webapp</directory>
                            <filtering>true</filtering>
                        </resource>
                    </webResources>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <id>dev</id>
            <properties>
                <target.environment>dev</target.environment>
            </properties>
        </profile>

        <profile>
            <id>prod</id>
            <properties>
                <target.environment>prod</target.environment>
            </properties>
        </profile>
    </profiles>
</project>

Erklärung

provided bedeutet: Die API wird zum Kompilieren benötigt, aber nicht ins WAR gepackt, weil der Application Server sie bereitstellt.

Typisches Deployment:

mvn clean package -Pprod

Ergebnis:

target/customer-portal.war

5. Projekt D: Batch- und Integration-Job mit Datenbankmigration

5.1 Szenario

Ein Enterprise-Batch-Job verarbeitet nächtlich CSV-Dateien, schreibt Daten in PostgreSQL und veröffentlicht Events.

Dieses Beispiel zeigt:

  • Spring Boot Batch-Anwendung
  • Flyway Migrationen
  • Failsafe Integrationstests
  • Docker Image Build mit Jib
  • getrennte Profile für local, ci, release

5.2 Projektstruktur

acme-billing-batch/
├── pom.xml
├── billing-batch-core/
│   └── pom.xml
├── billing-batch-app/
│   └── pom.xml
└── billing-batch-it/
    └── pom.xml

5.3 Root-POM

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.acme.billing</groupId>
    <artifactId>acme-billing-batch</artifactId>
    <version>2.8.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <module>billing-batch-core</module>
        <module>billing-batch-app</module>
        <module>billing-batch-it</module>
    </modules>

    <properties>
        <java.version>21</java.version>
        <spring.boot.version>4.1.0</spring.boot.version>
        <jib.plugin.version>3.4.6</jib.plugin.version>
        <flyway.plugin.version>11.13.2</flyway.plugin.version>
        <maven.failsafe.plugin.version>3.5.4</maven.failsafe.plugin.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring.boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-failsafe-plugin</artifactId>
                    <version>${maven.failsafe.plugin.version}</version>
                </plugin>

                <plugin>
                    <groupId>com.google.cloud.tools</groupId>
                    <artifactId>jib-maven-plugin</artifactId>
                    <version>${jib.plugin.version}</version>
                </plugin>

                <plugin>
                    <groupId>org.flywaydb</groupId>
                    <artifactId>flyway-maven-plugin</artifactId>
                    <version>${flyway.plugin.version}</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

5.4 Core-Modul

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.acme.billing</groupId>
        <artifactId>acme-billing-batch</artifactId>
        <version>2.8.0-SNAPSHOT</version>
    </parent>

    <artifactId>billing-batch-core</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework.batch</groupId>
            <artifactId>spring-batch-core</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
        </dependency>
    </dependencies>
</project>

5.5 App-Modul mit Spring Boot und Jib

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.acme.billing</groupId>
        <artifactId>acme-billing-batch</artifactId>
        <version>2.8.0-SNAPSHOT</version>
    </parent>

    <artifactId>billing-batch-app</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>com.acme.billing</groupId>
            <artifactId>billing-batch-core</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-batch</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring.boot.version}</version>
            </plugin>

            <plugin>
                <groupId>com.google.cloud.tools</groupId>
                <artifactId>jib-maven-plugin</artifactId>
                <configuration>
                    <from>
                        <image>eclipse-temurin:21-jre</image>
                    </from>
                    <to>
                        <image>registry.acme.example/billing/billing-batch:${project.version}</image>
                    </to>
                    <container>
                        <mainClass>com.acme.billing.BillingBatchApplication</mainClass>
                        <creationTime>USE_CURRENT_TIMESTAMP</creationTime>
                    </container>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Erklärung

Das App-Modul ist startbar und kann ein Container Image bauen.

Typische Befehle:

mvn clean package
mvn -pl billing-batch-app jib:build

5.6 Integration-Test-Modul

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.acme.billing</groupId>
        <artifactId>acme-billing-batch</artifactId>
        <version>2.8.0-SNAPSHOT</version>
    </parent>

    <artifactId>billing-batch-it</artifactId>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>com.acme.billing</groupId>
            <artifactId>billing-batch-app</artifactId>
            <version>${project.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>postgresql</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

5.7 Flyway-Migrationen ausführen

In echten Projekten wird Flyway häufig durch die Anwendung selbst ausgeführt. Manchmal möchte man Migrationen explizit per Maven starten.

Beispiel:

mvn -pl billing-batch-app flyway:migrate \
  -Dflyway.url=jdbc:postgresql://localhost:5432/billing \
  -Dflyway.user=billing \
  -Dflyway.password=secret

Enterprise-Hinweis:

Passwörter gehören nicht in die POM. Sie sollten über CI-Secrets, Umgebungsvariablen oder Maven settings.xml kommen.


6. Projekt E: Build-Quality-Gate Parent für Enterprise-Projekte

6.1 Szenario

Ein Unternehmen möchte Qualitätssicherung standardisieren.

Dieser Parent erzwingt:

  • Java-Version
  • Maven-Version
  • Dependency-Konvergenz
  • Unit Tests
  • Integrationstests
  • Code Coverage
  • statische Analyse
  • reproduzierbare Builds

6.2 Projektstruktur

acme-quality-parent/
└── pom.xml

6.3 Quality Parent POM

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.acme.quality</groupId>
    <artifactId>acme-quality-parent</artifactId>
    <version>1.3.0</version>
    <packaging>pom</packaging>

    <properties>
        <java.version>21</java.version>
        <maven.compiler.plugin.version>4.0.0-beta-3</maven.compiler.plugin.version>
        <maven.enforcer.plugin.version>3.6.2</maven.enforcer.plugin.version>
        <maven.surefire.plugin.version>3.5.4</maven.surefire.plugin.version>
        <maven.failsafe.plugin.version>3.5.4</maven.failsafe.plugin.version>
        <jacoco.plugin.version>0.8.13</jacoco.plugin.version>
        <spotbugs.plugin.version>4.9.4.0</spotbugs.plugin.version>
        <checkstyle.plugin.version>3.6.0</checkstyle.plugin.version>
    </properties>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>${maven.compiler.plugin.version}</version>
                    <configuration>
                        <release>${java.version}</release>
                        <showWarnings>true</showWarnings>
                    </configuration>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-enforcer-plugin</artifactId>
                    <version>${maven.enforcer.plugin.version}</version>
                    <executions>
                        <execution>
                            <id>enforce-enterprise-standards</id>
                            <goals>
                                <goal>enforce</goal>
                            </goals>
                            <configuration>
                                <rules>
                                    <requireJavaVersion>
                                        <version>[21,)</version>
                                    </requireJavaVersion>
                                    <requireMavenVersion>
                                        <version>[3.9.0,)</version>
                                    </requireMavenVersion>
                                    <dependencyConvergence />
                                    <banDuplicatePomDependencyVersions />
                                </rules>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>${maven.surefire.plugin.version}</version>
                    <configuration>
                        <includes>
                            <include>**/*Test.java</include>
                        </includes>
                    </configuration>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-failsafe-plugin</artifactId>
                    <version>${maven.failsafe.plugin.version}</version>
                    <configuration>
                        <includes>
                            <include>**/*IT.java</include>
                        </includes>
                    </configuration>
                    <executions>
                        <execution>
                            <id>integration-tests</id>
                            <goals>
                                <goal>integration-test</goal>
                                <goal>verify</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>

                <plugin>
                    <groupId>org.jacoco</groupId>
                    <artifactId>jacoco-maven-plugin</artifactId>
                    <version>${jacoco.plugin.version}</version>
                    <executions>
                        <execution>
                            <id>prepare-agent</id>
                            <goals>
                                <goal>prepare-agent</goal>
                            </goals>
                        </execution>
                        <execution>
                            <id>report</id>
                            <phase>verify</phase>
                            <goals>
                                <goal>report</goal>
                            </goals>
                        </execution>
                        <execution>
                            <id>check</id>
                            <phase>verify</phase>
                            <goals>
                                <goal>check</goal>
                            </goals>
                            <configuration>
                                <rules>
                                    <rule>
                                        <element>BUNDLE</element>
                                        <limits>
                                            <limit>
                                                <counter>LINE</counter>
                                                <value>COVEREDRATIO</value>
                                                <minimum>0.80</minimum>
                                            </limit>
                                        </limits>
                                    </rule>
                                </rules>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>

                <plugin>
                    <groupId>com.github.spotbugs</groupId>
                    <artifactId>spotbugs-maven-plugin</artifactId>
                    <version>${spotbugs.plugin.version}</version>
                    <configuration>
                        <effort>Max</effort>
                        <threshold>Medium</threshold>
                        <failOnError>true</failOnError>
                    </configuration>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-checkstyle-plugin</artifactId>
                    <version>${checkstyle.plugin.version}</version>
                    <configuration>
                        <configLocation>acme-checkstyle.xml</configLocation>
                        <consoleOutput>true</consoleOutput>
                        <failsOnError>true</failsOnError>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-enforcer-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <id>quality</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>com.github.spotbugs</groupId>
                        <artifactId>spotbugs-maven-plugin</artifactId>
                        <executions>
                            <execution>
                                <phase>verify</phase>
                                <goals>
                                    <goal>check</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>

                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-checkstyle-plugin</artifactId>
                        <executions>
                            <execution>
                                <phase>verify</phase>
                                <goals>
                                    <goal>check</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
</project>

6.4 Erklärung

Dieser Parent trennt normale Build-Regeln von teuren Quality Checks.

Standard-Build:

mvn clean verify

Build mit statischer Analyse:

mvn clean verify -Pquality

Enterprise-Vorteil:

  • Teams haben eine gemeinsame Qualitätsbasis.
  • CI/CD kann Quality Gates erzwingen.
  • Plugin-Versionen sind zentral kontrolliert.
  • Build-Verhalten wird reproduzierbarer.

7. Plugin-Erklärungen

7.1 maven-compiler-plugin

Zweck

Kompiliert Java-Code.

Wichtige Konfiguration

<release>${java.version}</release>

release ist in modernen Builds meist besser als getrennte source- und target-Werte, weil nicht nur Bytecode-Version, sondern auch verfügbare Java-API berücksichtigt wird.

Enterprise-Relevanz

  • verhindert versehentliche Nutzung falscher Java-Versionen
  • sorgt für konsistente Artefakte
  • wichtig für CI/CD und Runtime-Kompatibilität

7.2 maven-surefire-plugin

Zweck

Führt Unit Tests aus.

Typische Testnamen

*Test.java
*Tests.java

Lifecycle

Surefire läuft typischerweise in der Phase test.


7.3 maven-failsafe-plugin

Zweck

Führt Integrationstests aus.

Typische Testnamen

*IT.java
*ITCase.java

Lifecycle

Failsafe wird typischerweise an diese Phasen gebunden:

  • integration-test
  • verify

Warum nicht Surefire?

Integrationstests brauchen häufig externe Systeme wie Datenbank, Message Broker oder Testcontainers. Failsafe behandelt Fehler so, dass Cleanup-Schritte im Maven-Lifecycle zuverlässiger ausgeführt werden können.


7.4 maven-enforcer-plugin

Zweck

Erzwingt Build-Regeln.

Beispiele:

  • minimale Maven-Version
  • minimale Java-Version
  • Dependency-Konvergenz
  • keine doppelten Dependency-Versionen

Enterprise-Relevanz

Sehr wichtig, weil in großen Organisationen viele Teams mit unterschiedlichen lokalen Setups arbeiten.


7.5 jacoco-maven-plugin

Zweck

Misst Testabdeckung.

Typische Ziele

  • prepare-agent
  • report
  • check

Enterprise-Relevanz

Ermöglicht messbare Quality Gates, z. B. mindestens 80 Prozent Line Coverage.

Wichtig: Coverage ist kein Qualitätsbeweis, aber ein nützlicher Mindestindikator.


7.6 spring-boot-maven-plugin

Zweck

Unterstützt Spring Boot in Maven.

Typische Aufgaben:

  • ausführbares JAR oder WAR erzeugen
  • Anwendung starten
  • Build-Informationen erzeugen
  • Repackage eines Artefakts

Enterprise-Relevanz

Wichtig für Microservices, Containerisierung und Cloud Deployments.


7.7 maven-war-plugin

Zweck

Erstellt WAR-Dateien.

Typischer Einsatz

  • klassische Webanwendungen
  • Deployment auf Application Servern
  • Legacy-Jakarta-EE-Projekte

7.8 flatten-maven-plugin

Zweck

Erzeugt eine vereinfachte POM für Veröffentlichung.

Enterprise-Relevanz

Nützlich bei CI-freundlichen Versionen, Parent-Strukturen und internen Artefakt-Repositories.


7.9 jib-maven-plugin

Zweck

Baut Container Images für Java-Anwendungen ohne klassisches Dockerfile.

Enterprise-Relevanz

Hilfreich für CI/CD, wenn Container Images standardisiert erzeugt und in eine Registry gepusht werden sollen.


7.10 flyway-maven-plugin

Zweck

Führt Datenbankmigrationen aus.

Enterprise-Relevanz

Datenbankschemata werden versioniert und reproduzierbar ausgerollt.

Wichtig: Zugangsdaten gehören nicht in die POM.


7.11 build-helper-maven-plugin

Zweck

Erweitert den Build, z. B. durch zusätzliche Source-Verzeichnisse.

Typische Verwendung

  • generierte Quellen einbinden
  • zusätzliche Test-Sources registrieren
  • Build-Metadaten erzeugen

7.12 spotbugs-maven-plugin

Zweck

Findet potenzielle Fehler im Bytecode.

Enterprise-Relevanz

Hilft bei großen Codebasen, riskante Muster automatisiert zu erkennen.


7.13 maven-checkstyle-plugin

Zweck

Prüft Code-Style-Regeln.

Enterprise-Relevanz

Sorgt für einheitlichen Stil über Teams hinweg.


8. Dependency-Management-Erklärungen

8.1 Warum BOMs verwenden?

BOMs reduzieren Versionschaos.

Ohne BOM:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>4.1.0</version>
</dependency>

Mit BOM:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Die Version kommt aus dependencyManagement.


8.2 Interne BOM vs. externe BOM

Externe BOM

Beispiele:

  • Spring Boot BOM
  • JUnit BOM
  • Testcontainers BOM
  • Jackson BOM

Interne BOM

Eine interne BOM verwaltet zusätzlich Firmenbibliotheken.

Beispiel:

<dependency>
    <groupId>com.acme.platform</groupId>
    <artifactId>acme-security-starter</artifactId>
    <version>${project.version}</version>
</dependency>

8.3 Typische Dependency Scopes

Scope Erklärung Beispiel
compile Standard, zur Compile- und Laufzeit verfügbar Fachbibliothek
provided Compile-Zeit, aber Runtime stellt es bereit Jakarta EE API im Application Server
runtime Nur zur Laufzeit nötig JDBC-Treiber
test Nur für Tests JUnit, Testcontainers
import Nur für BOM-Import in dependencyManagement Spring Boot BOM

8.4 Transitive Dependencies

Maven lädt nicht nur direkte Dependencies, sondern auch deren Abhängigkeiten.

Problem:

service-a -> library-x -> vulnerable-lib:1.0
service-a -> library-y -> vulnerable-lib:2.0

Mögliche Folge:

  • Versionskonflikte
  • Security-Probleme
  • unerwartetes Laufzeitverhalten

Gegenmaßnahmen:

  • BOMs
  • Dependency Convergence Checks
  • Security Scans
  • gezielte Exclusions
  • regelmäßige Updates

9. Build-Kommandos und typische Maven-Abläufe

9.1 Komplettes Projekt bauen

mvn clean install

9.2 Projekt bis Quality-Gate bauen

mvn clean verify

9.3 Mit Profil bauen

mvn clean verify -Pci

9.4 Einzelnes Modul bauen

mvn clean install -pl order-web

9.5 Einzelnes Modul plus benötigte Module bauen

mvn clean install -pl order-web -am

9.6 Abhängige Module ebenfalls bauen

mvn clean install -pl order-domain -amd

9.7 Dependency Tree anzeigen

mvn dependency:tree

9.8 Effektive POM anzeigen

mvn help:effective-pom

Sehr hilfreich, um Vererbung, Profile und Plugin-Konfigurationen zu verstehen.


10. Checkliste für eigene Enterprise-POMs

10.1 Struktur

  • Gibt es eine klare Root-POM?
  • Ist packaging=pom bei Aggregatoren korrekt gesetzt?
  • Sind Module logisch getrennt?
  • Gibt es eine klare Parent-POM?
  • Ist eine BOM sinnvoll?

10.2 Versionen

  • Werden Dependency-Versionen zentral verwaltet?
  • Werden Plugin-Versionen zentral verwaltet?
  • Gibt es harte Versionen in Child-Modulen?
  • Gibt es Snapshot-Dependencies in Release-Builds?

10.3 Build

  • Ist Java-Version eindeutig definiert?
  • Nutzt der Compiler release?
  • Sind Unit Tests und Integrationstests getrennt?
  • Sind Plugin-Versionen fixiert?
  • Gibt es Enforcer-Regeln?

10.4 Sicherheit

  • Gibt es Dependency-Konvergenzprüfungen?
  • Gibt es Security Scans in CI?
  • Werden Secrets aus der POM herausgehalten?
  • Gibt es eine Regel gegen unsichere Repositories?

10.5 Deployment

  • Ist distributionManagement korrekt?
  • Sind Snapshot- und Release-Repositories getrennt?
  • Werden Container Images reproduzierbar gebaut?
  • Ist klar, welches Modul deployt wird?

10.6 Wartbarkeit

  • Sind Profiles verständlich benannt?
  • Sind Properties sprechend?
  • Sind technische Starter sinnvoll getrennt?
  • Gibt es Dokumentation für jedes Modul?
  • Ist mvn help:effective-pom nachvollziehbar?

11. Empfohlenes Lernvorgehen

Schritt 1: Root-POM lesen

Fragen:

  • Welche Module gibt es?
  • Welche Versionen sind zentral definiert?
  • Welche BOMs werden importiert?
  • Welche Plugins sind zentral verwaltet?

Schritt 2: Modul-POMs lesen

Fragen:

  • Welche Aufgabe hat das Modul?
  • Welche internen Module werden verwendet?
  • Welche externen Libraries werden verwendet?
  • Welche Scopes kommen vor?

Schritt 3: Effektive POM erzeugen

mvn help:effective-pom

Damit sieht man die finale Maven-Konfiguration nach Vererbung und Profilauflösung.

Schritt 4: Dependency Tree prüfen

mvn dependency:tree

Damit sieht man transitive Dependencies und mögliche Konflikte.

Schritt 5: Build-Lifecycle verstehen

mvn clean verify -X

-X erzeugt Debug-Ausgabe. Für Anfänger ist das sehr viel, aber für tiefe Fehleranalyse nützlich.


12. Zusammenfassung

Dieses Buch hat fünf Enterprise-Maven-Beispiele gezeigt:

  1. Multi-Module Spring Boot Service
    Moderne Microservice-Struktur mit Domain, Application, Infrastructure, Web und Integration Tests.

  2. Unternehmens-BOM und Shared Libraries
    Zentrale Dependency- und Build-Standards für mehrere Teams.

  3. Legacy Jakarta EE WAR
    Klassische Enterprise-Webanwendung für Application Server.

  4. Batch- und Integration-Job
    Batch-Verarbeitung mit Datenbankmigration, Integrationstests und Container Image Build.

  5. Quality-Gate Parent
    Firmenweiter Parent für Build-Regeln, Tests, Coverage und statische Analyse.

Die wichtigsten Maven-Prinzipien sind:

  • Versionen zentralisieren
  • Build-Konventionen standardisieren
  • Parent-POM, BOM und Aggregator sauber trennen
  • Unit Tests und Integrationstests getrennt ausführen
  • Secrets nie in POM-Dateien speichern
  • CI/CD als Teil des Build-Designs betrachten
  • dependencyManagement und pluginManagement bewusst einsetzen

13. Mini-Glossar

Begriff Bedeutung
POM Project Object Model, zentrale Maven-Konfiguration
Parent-POM Vererbt gemeinsame Einstellungen
Aggregator-POM Baut mehrere Module gemeinsam
BOM Bill of Materials, zentrale Dependency-Versionen
Plugin Maven-Erweiterung für Build-Aufgaben
Goal Einzelne Aufgabe eines Plugins
Phase Schritt im Maven-Lifecycle
Profile Build-Variante für Umgebung oder Zweck
Scope Gültigkeitsbereich einer Dependency
Transitive Dependency Indirekte Abhängigkeit über andere Libraries
Effective POM Finale POM nach Vererbung und Profilauflösung

14. Quellen und Referenzen

Die Beispiele orientieren sich an den offiziellen Maven- und Spring-Boot-Konzepten:

  • Apache Maven POM Reference
  • Apache Maven Introduction to the Build Lifecycle
  • Apache Maven Introduction to Build Profiles
  • Apache Maven Multiple Modules Guide
  • Apache Maven Compiler Plugin Dokumentation
  • Spring Boot Maven Plugin Dokumentation

11. Visualisierungen: Enterprise-POMs besser verstehen

Dieses Kapitel ergänzt das Beispielbuch um zusätzliche SVG-Diagramme. Die Bilder sind bewusst nicht als Dekoration gedacht, sondern als Lesehilfe für komplexe POM-Dateien. Nutze sie, wenn du eine fremde Unternehmens-POM analysierst oder eigene Build-Standards dokumentieren möchtest.

11.1 POM als Enterprise-Vertrag

POM als Enterprise-Vertrag
Die POM bündelt technische Entscheidungen zu Dependencies, Plugins, Profiles, Repositories und CI/CD.

Was zeigt das Diagramm?
Die pom.xml steht in der Mitte, weil viele Unternehmensstandards dort zusammenlaufen. Links liegen Dependencies und Plugins, rechts Profiles und Repositories. Oben wirken Parent-POM oder BOM hinein; unten wird daraus ein CI/CD-Build.

Warum ist das wichtig?
In Enterprise-Projekten ist eine POM oft ein Vertrag: Sie legt fest, welche Versionen erlaubt sind, wie getestet wird, wie Artefakte heißen und wohin sie deployed werden.

So liest du das in echten Projekten:
Prüfe zuerst Parent, dependencyManagement, pluginManagement, Profiles und distributionManagement. Danach erst einzelne Dependencies oder Plugin-Details.


11.2 Effective POM: Was Maven wirklich sieht

Effective POM aus Super POM, Parent, Modul-POM und Profiles
Die Effective POM ist das Ergebnis aus Maven-Defaults, Parent-POMs, Modul-POMs und aktiven Profiles.

Was zeigt das Diagramm?
Maven kombiniert die Super POM, Unternehmens-Parent, Modul-POM und aktive Profiles zu einer endgültigen Konfiguration.

Warum ist das wichtig?
Viele Build-Probleme sind nicht direkt in der sichtbaren Modul-POM erkennbar, weil Versionen, Plugin-Konfigurationen oder Repositories geerbt werden.

Praxisbefehl:

mvn help:effective-pom
mvn help:effective-settings

11.3 BOM-Layering in Enterprise-Projekten

BOM-Layering mit externen BOMs, Unternehmens-BOM und Service-POMs
Eine Unternehmens-BOM bündelt externe BOMs und gibt konsistente Versionen an viele Module weiter.

Was zeigt das Diagramm?
Externe BOMs wie Spring Boot, Testcontainers oder Cloud-BOMs werden in einer eigenen Platform-BOM gebündelt. Services nutzen danach Dependencies ohne lokale Versionsduplikate.

Warum ist das wichtig?
Ohne zentrale BOM entstehen Versionsdrift, Sicherheitslücken und schwer nachvollziehbare Konflikte zwischen Teams.

Analysefrage:
Welche Versionen stehen in Child-POMs direkt und welche kommen aus einer BOM? Direkte Versionen in vielen Child-POMs sind oft ein Wartungsrisiko.


11.4 pluginManagement vs. plugins

pluginManagement definiert Standards, plugins aktiviert Ausführung
`pluginManagement` definiert Standards; der `plugins`-Block aktiviert konkrete Plugin-Ausführungen.

Was zeigt das Diagramm?
Die Parent-POM definiert Versionen und Standardkonfigurationen. Ein Modul aktiviert das Plugin im plugins-Block. Maven führt Plugin-Goals dann in Lifecycle-Phasen wie compile, test oder verify aus.

Typischer Fehler:
Ein Plugin steht nur in pluginManagement, wird aber nie unter plugins aktiviert. Dann ist es zwar verwaltet, läuft aber nicht automatisch.


11.5 Dependency-Auflösung und Konflikte

Dependency Tree mit transitiven Dependencies und Konflikten
Transitive Dependencies können Konflikte erzeugen; `dependencyManagement` macht die gewählte Version bewusst.

Was zeigt das Diagramm?
Ein Service bringt direkte Dependencies mit. Diese bringen wiederum transitive Dependencies. Wenn zwei Pfade verschiedene Versionen derselben Library liefern, muss die Entscheidung nachvollziehbar sein.

Praxisbefehle:

mvn dependency:tree
mvn dependency:tree -Dincludes=org.slf4j
mvn dependency:tree -Dverbose

11.6 Modulgrenzen und Verantwortlichkeiten

Multi-Module Projekt mit Shared Libraries und Services
Gute Modulgrenzen zeigen fachliche Verantwortung, technische Wiederverwendung und Build-Abhängigkeiten.

Was zeigt das Diagramm?
Ein Root-Aggregator baut Shared Libraries, Event Contracts, Services und Test-Hilfen gemeinsam. Die Pfeile zeigen, welche Module andere Module verwenden.

Warum ist das wichtig?
Ein Multi-Module-Build wird schwer wartbar, wenn alle Module alles voneinander kennen. Gute Grenzen reduzieren Build-Zeit, Kopplung und Release-Risiko.


11.7 Profiles und Umgebungen

Matrix für Maven Profiles in dev, test/ci und prod
Profiles sollten gezielt Unterschiede aktivieren, nicht komplette Build-Logik verstecken.

Was zeigt das Diagramm?
dev, test/ci und prod unterscheiden sich häufig bei Datenbank, Tests, Quality Gates und Artefakt-Strategie.

Best Practice:
Vermeide Profiles, die den Build komplett verändern. Profiles sollten Unterschiede sichtbar und begrenzt halten.


11.8 CI-Quality-Pipeline

Maven CI Pipeline mit validate, compile, test, verify, package und deploy
Eine CI-Pipeline nutzt Maven-Phasen als Qualitätsstufen.

Was zeigt das Diagramm?
Der Build beginnt mit Enforcer-Regeln, kompiliert Code, führt Unit Tests aus, prüft Integrationstests und Qualitätsmetriken und veröffentlicht erst danach Artefakte.

Typische Pull-Request-Regel:

mvn -B clean verify -Pci

11.9 Snapshot- und Release-Fluss

Snapshot und Release Repository Flow
Snapshots sind beweglich; Releases sollten unveränderbar und auditierbar sein.

Was zeigt das Diagramm?
Feature-Branches erzeugen häufig SNAPSHOT-Artefakte. Ein Release-Branch oder Tag erzeugt unveränderbare Release-Artefakte.

Wichtige POM-Stelle:
distributionManagement entscheidet, wohin mvn deploy veröffentlicht.


11.10 Maven-Troubleshooting-Fluss

Troubleshooting Flow für Maven Build Fehler
Build-Fehler lassen sich schneller lösen, wenn man zuerst Ursache und Maven-Ebene eingrenzt.

Was zeigt das Diagramm?
Ein Build-Fehler wird zuerst grob sortiert: Dependency, Plugin, Test oder Umgebung/Profile. Danach nutzt man gezielte Maven-Befehle.

Debug-Werkzeuge:

mvn -X clean verify
mvn help:effective-pom
mvn dependency:tree
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-surefire-plugin
⌂ Cockpit