1. Compilation de projets modulaires: principes de base
Compilateur et chemin de module (module-path)
Avant l’apparition des modules, toute l’application était compilée et exécutée à l’aide du classpath — une simple liste de répertoires et de fichiers JAR dans lesquels Java cherchait les classes. Avec le système de modules, un nouvel acteur est apparu — le module-path. Désormais, le compilateur et la JVM doivent savoir non seulement où se trouvent les classes, mais aussi à quels modules elles appartiennent, quelles dépendances elles ont et quels packages sont exportés.
Point clé:
- Pour les projets modulaires, utilisez --module-path au lieu de -classpath.
- Le compilateur et la JVM doivent voir tous les modules nécessaires à votre application (et leurs dépendances).
Exemple: compilation manuelle des modules
Supposons que vous ayez deux modules: core et app, où app dépend de core.
Structure des répertoires:
project-root/
core/
src/
main/
java/
module-info.java
com/example/core/...
app/
src/
main/
java/
module-info.java
com/example/app/...
Compilation manuelle (démonstration):
# On commence par compiler core
javac -d out/core core/src/main/java/module-info.java core/src/main/java/com/example/core/*.java
# Puis app, en indiquant module-path vers core
javac --module-path out/core -d out/app app/src/main/java/module-info.java app/src/main/java/com/example/app/*.java
Exécution:
java --module-path out/core:out/app -m app/com.example.app.Main
Dans des projets réels, pas besoin de le faire à la main — utilisez Maven/Gradle ou l’IDE.
2. Maven: compilation de projets multi-modules
Structure d’un projet multi-modules avec Maven
Maven prend en charge depuis longtemps une structure avec plusieurs modules (submodules). Avec l’arrivée du système de modules Java, ces « modules » Maven coïncident souvent avec les modules Java, mais pas toujours: un module Maven est simplement un sous-projet, tandis qu’un module Java est ce qui est décrit dans module-info.java. En général, un module Maven = un module Java.
Structure typique:
myproject/
pom.xml # POM parent
core/
pom.xml # Module core
src/main/java/
module-info.java
com/example/core/...
app/
pom.xml # Module app
src/main/java/
module-info.java
com/example/app/...
Exemple de 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>
Exemple de POM pour le module core (core/pom.xml):
<project>
<parent>
<groupId>com.example</groupId>
<artifactId>myproject</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>core</artifactId>
<dependencies>
<!-- Des dépendances peuvent être ajoutées ici, par exemple vers d'autres modules ou des bibliothèques tierces -->
</dependencies>
</project>
Exemple de POM pour le module 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>
Important:
- Si app a besoin de core, le module-info.java du module app doit contenir requires core;
- Maven résoudra les dépendances si <dependency> et <module> sont correctement définis.
Comment Maven prend en compte module-info.java
- Maven compile automatiquement module-info.java avec les autres classes.
- Si vous avez des dépendances modulaires, Maven les ajoutera au module-path lors de la compilation et de l’exécution.
- Si vous utilisez d’anciens plugins ou une version de Java antérieure à 9 — le système de modules ne fonctionnera pas.
Exécuter une application modulaire via Maven
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<release>21</release> <!-- ou votre version de Java -->
</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
Erreurs courantes avec Maven et les modules
Erreur: « module not found ». Vous n’avez pas indiqué le bon module-path ou la <dependency> pour l’artéfact dépendant n’est pas déclarée.
Duplication des noms de modules. Le projet ne doit pas contenir deux modules portant le même nom (par exemple, deux module core).
Exports/requires manquants. Si vous oubliez d’exporter un package (exports) ou de déclarer une dépendance (requires), vous obtiendrez une erreur de compilation.
Mélange de classpath et module-path. N’utilisez pas de plugins/configurations obsolètes ne prenant pas en charge les modules: cela mène à des erreurs imprévisibles.
3. Gradle: compilation de projets multi-modules
Structure d’un projet 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 (racine)
subprojects {
apply plugin: 'java'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21) // ou votre version de Java
}
}
repositories {
mavenCentral()
}
}
build.gradle pour core
plugins {
id 'java'
}
group = 'com.example'
version = '1.0-SNAPSHOT'
build.gradle pour app
plugins {
id 'java'
id 'application'
}
group = 'com.example'
version = '1.0-SNAPSHOT'
dependencies {
implementation project(':core')
}
application {
mainModule = 'app' // Nom de votre module Java
mainClass = 'com.example.app.Main'
}
Compilation et exécution
./gradlew build
./gradlew :app:run
Gradle détecte automatiquement le module-path lorsqu’il trouve module-info.java. Si quelque chose ne fonctionne pas — vérifiez que vous utilisez une version récente de Gradle et des plugins.
4. IntelliJ IDEA: création et configuration d’un projet modulaire
Création d’un projet modulaire
- File → New → Project → Java → activez « Create module-info.java ».
- Pour un projet multi-modules: File → New → Module — ajoutez de nouveaux modules au projet.
- Si vous utilisez Maven/Gradle — importez simplement le projet via pom.xml ou build.gradle.
Structure dans IDEA
- Dans Project View, chaque module est affiché comme une branche distincte.
- Dans chaque module — son propre module-info.java, ses sources.
- IDEA indique quels modules exportent/exigent quels packages (exports/requires).
- Si vous oubliez d’exporter un package ou de déclarer une dépendance — IDEA mettra l’erreur en évidence.
Vérification du module-path, exécution de la classe main
- Dans Run/Debug Configurations, indiquez:
- Main class (par exemple, com.example.app.Main)
- Module (par exemple, app)
- IDEA se charge du module-path.
- Si vous lancez via Maven/Gradle — utilisez les configurations correspondantes (par exemple, app [run]).
Importer des modules et bibliothèques tiers
- Pour travailler avec des bibliothèques externes (par exemple, requires java.sql; ou des JAR tiers) — ajoutez la dépendance via Maven/Gradle.
- Si la bibliothèque n’est pas modulaire (pas de module-info.java), elle sera automatiquement ajoutée au « unnamed module » (c’est normal pour la plupart des bibliothèques).
5. Pratique: créer un projet multi-modules simple
Étape 1. Créer la structure du projet
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 "Bonjour du module core !";
}
}
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;
}
Étape 2. Compilation et exécution avec Maven
À la racine du projet, créez un pom.xml parent et deux sous-projets (core/pom.xml, app/pom.xml) comme ci-dessus. Dans app/pom.xml, ajoutez la dépendance vers core.
mvn clean install
mvn -pl app exec:java
Étape 3. Compilation et exécution avec Gradle
Créez settings.gradle, le build.gradle racine, et un par module. Dans app/build.gradle, déclarez la dépendance vers core et la mainClass.
./gradlew build
./gradlew :app:run
Étape 4. Import et exécution dans IntelliJ IDEA
- Ouvrez la racine du projet via File → Open.
- IDEA détecte la structure Maven/Gradle, crée les modules.
- Dans chaque module, vous pouvez ouvrir module-info.java; IDEA affichera les relations entre modules.
- Lancez Main.java via le menu contextuel (« Run Main.main() ») — IDEA configurera le module-path automatiquement.
6. Erreurs courantes lors de la compilation de projets modulaires
Erreur n° 1: module-path incorrect. Si, lors de l’exécution ou de la compilation, un message tel que « module not found » ou « package is not visible » apparaît, il est probable que vous n’ayez pas indiqué un module-path correct ou que vous ayez oublié d’ajouter une dépendance dans pom.xml/build.gradle.
Erreur n° 2: duplication des noms de modules. Le projet ne doit pas contenir deux modules portant le même nom (par exemple, deux module core). Cela entraîne une erreur de compilation.
Erreur n° 3: paquet non exporté. Si une classe se trouve dans un package qui n’est pas exporté via exports dans module-info.java, elle ne sera pas accessible aux autres modules, même si elle est public. Une erreur de compilation surviendra lors de la tentative d’utilisation de cette classe.
Erreur n° 4: requires non déclaré. Si un module utilise des classes d’un autre module mais n’a pas indiqué requires dans son module-info.java, le compilateur produira une erreur.
Erreur n° 5: incompatibilité avec des bibliothèques externes. Le décalage entre les modules et les bibliothèques sans module-info.java (elles vont dans le « unnamed module ») ne gêne généralement pas, mais certaines configurations peuvent nécessiter des réglages supplémentaires.
Erreur n° 6: lancement depuis le mauvais module. Dans la configuration de lancement de IDEA ou de Maven/Gradle, la classe main ou le module est incorrect — l’application ne démarre pas. Vérifiez Main, mainModule/module et le profil utilisé.
GO TO FULL VERSION