CodeGym /Kurse /JAVA 25 SELF /Erstellung von Mehrmodulprojekten: Maven, Gradle, IDEA

Erstellung von Mehrmodulprojekten: Maven, Gradle, IDEA

JAVA 25 SELF
Level 60, Lektion 4
Verfügbar

1. Build modularer Projekte: Grundprinzipien

Compiler und Modulpfad (module-path)

Vor der Einführung von Modulen wurde die gesamte Anwendung mit dem sogenannten classpath kompiliert und gestartet – einfach einer Liste von Verzeichnissen und JAR-Dateien, in denen Java Klassen suchte. Im Modulsystem ist ein neuer Spieler hinzugekommen – der module-path. Jetzt müssen Compiler und JVM nicht nur wissen, wo die Klassen liegen, sondern auch, zu welchen Modulen sie gehören, welche Abhängigkeiten sie haben und welche Pakete exportiert werden.

Kernpunkt:

  • Für modulare Projekte verwenden Sie --module-path statt -classpath.
  • Compiler und JVM müssen alle Module sehen, die Ihre Anwendung benötigt (und deren Abhängigkeiten).

Beispiel: manuelle Kompilierung von Modulen

Angenommen, Sie haben zwei Module: core und app, wobei app von core abhängt.

Verzeichnisstruktur:

project-root/
  core/
    src/
      main/
        java/
          module-info.java
          com/example/core/...
  app/
    src/
      main/
        java/
          module-info.java
          com/example/app/...

Manuelle Kompilierung (Demonstration):

# Zuerst core kompilieren
javac -d out/core core/src/main/java/module-info.java core/src/main/java/com/example/core/*.java

# Dann app, wobei der module-path auf core zeigt
javac --module-path out/core -d out/app app/src/main/java/module-info.java app/src/main/java/com/example/app/*.java

Ausführung:

java --module-path out/core:out/app -m app/com.example.app.Main

In realen Projekten müssen Sie das nicht manuell tun – verwenden Sie Maven/Gradle oder die IDE.

2. Maven: Build von Mehrmodulprojekten

Struktur eines Mehrmodulprojekts in Maven

Maven unterstützt seit Langem eine Struktur mit mehreren Modulen (Submodules). Mit dem Java-Modulsystem fallen diese „Module“ von Maven oft mit den Java-Modulen zusammen, aber nicht immer: Ein Maven-Modul ist einfach ein Teilprojekt, während ein Java-Modul durch module-info.java definiert ist. In der Regel gilt: ein Maven‑Modul = ein Java‑Modul.

Typische Struktur:

myproject/
  pom.xml                # Parent POM
  core/
    pom.xml              # Modul core
    src/main/java/
      module-info.java
      com/example/core/...
  app/
    pom.xml              # Modul app
    src/main/java/
      module-info.java
      com/example/app/...

Beispiel für das Parent-POM (myproject/pom.xml):

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>myproject</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>
  <modules>
    <module>core</module>
    <module>app</module>
  </modules>
</project>

Beispiel-POM für das Modul core (core/pom.xml):

<project>
  <parent>
    <groupId>com.example</groupId>
    <artifactId>myproject</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <artifactId>core</artifactId>
  <dependencies>
    <!-- Hier können Abhängigkeiten stehen, z. B. auf andere Module oder Drittanbieter-Bibliotheken -->
  </dependencies>
</project>

Beispiel-POM für das Modul app (app/pom.xml):

<project>
  <parent>
    <groupId>com.example</groupId>
    <artifactId>myproject</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <artifactId>app</artifactId>
  <dependencies>
    <dependency>
      <groupId>com.example</groupId>
      <artifactId>core</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>
  </dependencies>
</project>

Wichtig:

  • Wenn app core benötigt, muss in der module-info.java von app ein requires core; stehen.
  • Maven verarbeitet die Abhängigkeiten automatisch, wenn <dependency> und <module> korrekt angegeben sind.

Wie Maven mit module-info.java umgeht

  • Maven kompiliert module-info.java automatisch zusammen mit den übrigen Klassen.
  • Wenn Sie modulare Abhängigkeiten haben, fügt Maven sie beim Kompilieren und Starten dem module-path hinzu.
  • Wenn Sie alte Plugins oder Java unter Version 9 verwenden – funktioniert das Modulsystem nicht.

Start eines modularen Programms über Maven

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.10.1</version>
      <configuration>
        <release>21</release> <!-- oder Ihre Java-Version -->
      </configuration>
    </plugin>
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>exec-maven-plugin</artifactId>
      <version>3.1.0</version>
      <configuration>
        <mainClass>com.example.app.Main</mainClass>
        <commandlineArgs></commandlineArgs>
      </configuration>
    </plugin>
  </plugins>
</build>
mvn clean install
mvn -pl app exec:java

Typische Fehler bei der Arbeit mit Maven und Modulen

Fehler: „module not found“. Der richtige module-path wurde nicht angegeben oder für das abhängige Artefakt fehlt die <dependency>.

Doppelte Modulnamen. Es darf nicht zwei Module mit demselben Namen im Projekt geben (z. B. zwei module core).

Fehlendes export/requires. Wenn Sie ein Paket nicht exportiert (exports) oder eine Abhängigkeit nicht deklariert haben (requires), führt das zu einem Kompilierfehler.

Mischen von classpath und module-path. Verwenden Sie keine veralteten Plugins/Einstellungen ohne Modulsupport – das führt zu unvorhersehbaren Fehlern.

3. Gradle: Build von Mehrmodulprojekten

Projektstruktur mit Gradle

myproject/
  settings.gradle
  build.gradle
  core/
    build.gradle
    src/main/java/module-info.java
    src/main/java/com/example/core/...
  app/
    build.gradle
    src/main/java/module-info.java
    src/main/java/com/example/app/...

settings.gradle

rootProject.name = 'myproject'
include 'core', 'app'

build.gradle (Root)

subprojects {
    apply plugin: 'java'

    java {
        toolchain {
            languageVersion = JavaLanguageVersion.of(21) // oder Ihre Java-Version
        }
    }

    repositories {
        mavenCentral()
    }
}

build.gradle für core

plugins {
    id 'java'
}

group = 'com.example'
version = '1.0-SNAPSHOT'

build.gradle für app

plugins {
    id 'java'
    id 'application'
}

group = 'com.example'
version = '1.0-SNAPSHOT'

dependencies {
    implementation project(':core')
}

application {
    mainModule = 'app' // Name Ihres Java-Moduls
    mainClass = 'com.example.app.Main'
}

Build und Ausführung

./gradlew build
./gradlew :app:run

Gradle erkennt den module-path automatisch, wenn es module-info.java findet. Falls etwas nicht funktioniert – prüfen Sie, ob Sie eine aktuelle Version von Gradle und den Plugins verwenden.

4. IntelliJ IDEA: Erstellen und Einrichten eines modularen Projekts

Erstellen eines modularen Projekts

  • File → New → Project → Java → aktivieren Sie „Create module-info.java“.
  • Für ein Mehrmodulprojekt: File → New → Module – fügen Sie dem Projekt neue Module hinzu.
  • Wenn Sie Maven/Gradle verwenden – importieren Sie das Projekt einfach über pom.xml oder build.gradle.

Struktur in IDEA

  • In der Project View wird jedes Modul als eigener Zweig angezeigt.
  • In jedem Modul gibt es eine eigene module-info.java und eigene Quellen.
  • IDEA zeigt an, welche Module welche Pakete exportieren/benötigen (exports/requires).
  • Wenn Sie vergessen, ein Paket zu exportieren oder eine Abhängigkeit zu deklarieren, markiert IDEA den Fehler.

Prüfen des module-path, Start der Main-Klasse

  • In den Run/Debug Configurations geben Sie an:
    • Main class (z. B. com.example.app.Main)
    • Module (z. B. app)
  • IDEA kümmert sich selbst um den module-path.
  • Wenn Sie über Maven/Gradle starten – verwenden Sie die entsprechenden Konfigurationen (z. B. app [run]).

Import externer Module und Bibliotheken

  • Für die Arbeit mit externen Bibliotheken (z. B. requires java.sql; oder fremde JARs) – fügen Sie die Abhängigkeit über Maven/Gradle hinzu.
  • Wenn die Bibliothek nicht modular ist (keine module-info.java), wird sie automatisch dem „unnamed module“ hinzugefügt (das ist für die meisten Bibliotheken in Ordnung).

5. Praxis: ein einfaches Mehrmodulprojekt erstellen

Schritt 1. Projektstruktur erstellen

myproject/
  core/
    src/main/java/module-info.java
    src/main/java/com/example/core/HelloService.java
  app/
    src/main/java/module-info.java
    src/main/java/com/example/app/Main.java

HelloService.java (core):

package com.example.core;

public class HelloService {
    public String getHello() {
        return "Hallo vom Core-Modul!";
    }
}

module-info.java (core):

module core {
    exports com.example.core;
}

Main.java (app):

package com.example.app;

import com.example.core.HelloService;

public class Main {
    public static void main(String[] args) {
        HelloService service = new HelloService();
        System.out.println(service.getHello());
    }
}

module-info.java (app):

module app {
    requires core;
}

Schritt 2. Build und Ausführung mit Maven

Im Projektroot erstellen wir ein Parent-pom.xml und zwei Teilprojekte (core/pom.xml, app/pom.xml) wie oben. In app/pom.xml fügen wir die Abhängigkeit zu core hinzu.

mvn clean install
mvn -pl app exec:java

Schritt 3. Build und Ausführung mit Gradle

Wir erstellen settings.gradle, das Root-build.gradle und je eines für jedes Modul. In app/build.gradle deklarieren wir die Abhängigkeit zu core und die mainClass.

./gradlew build
./gradlew :app:run

Schritt 4. Import und Start in IntelliJ IDEA

  • Öffnen Sie den Projektroot über File → Open.
  • IDEA erkennt die Maven/Gradle-Struktur und erstellt die Module.
  • In jedem Modul kann die module-info.java geöffnet werden; IDEA zeigt die Beziehungen zwischen den Modulen an.
  • Starten Sie Main.java über das Kontextmenü („Run Main.main()“) – IDEA setzt den module-path automatisch.

6. Typische Fehler beim Build modularer Projekte

Fehler Nr. 1: Falscher module-path. Wenn beim Starten oder Kompilieren Meldungen wie „module not found“ oder „package is not visible“ erscheinen, haben Sie wahrscheinlich den module-path nicht korrekt angegeben oder die Abhängigkeit in pom.xml/build.gradle vergessen.

Fehler Nr. 2: Doppelte Modulnamen. Es darf nicht zwei Module mit demselben Namen geben (z. B. zwei module core). Das führt zu einem Kompilierfehler.

Fehler Nr. 3: Nicht exportiertes Paket. Wenn sich eine Klasse in einem Paket befindet, das in der module-info.java nicht über exports exportiert wird, ist sie für andere Module nicht sichtbar, selbst wenn sie public ist. Beim Versuch, eine solche Klasse zu verwenden, tritt ein Kompilierfehler auf.

Fehler Nr. 4: Nicht deklariertes requires. Wenn ein Modul Klassen eines anderen Moduls verwendet, aber in module-info.java kein requires angibt, meldet der Compiler einen Fehler.

Fehler Nr. 5: Inkompatibilität mit externen Bibliotheken. Das Zusammenspiel von Modulen und Bibliotheken ohne module-info.java (sie landen im „unnamed module“) ist normalerweise unproblematisch, in manchen Konfigurationen kann jedoch zusätzliche Konfiguration nötig sein.

Fehler Nr. 6: Start aus dem falschen Modul. In der Run-Konfiguration von IDEA oder Maven/Gradle ist die falsche Main-Klasse oder das falsche Modul angegeben – die Anwendung startet nicht. Prüfen Sie Main, mainModule/module und das verwendete Profil.

1
Aufgabe
JAVA 25 SELF, Level 60, Lektion 4
Gesperrt
Aufbau einer multimodularen Projektfestung 🏰
Aufbau einer multimodularen Projektfestung 🏰
1
Aufgabe
JAVA 25 SELF, Level 60, Lektion 4
Gesperrt
Start des Herzstücks der Anwendung mit Maven ✨
Start des Herzstücks der Anwendung mit Maven ✨
1
Umfrage/Quiz
Module und Projektstruktur, Level 60, Lektion 4
Nicht verfügbar
Module und Projektstruktur
Module und Projektstruktur
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION