POO en Java · L2 · Section 6/7
Outillage et écosystème
Progression
#Outillage moderne : build, IDE, delivery
L'outillage est trop souvent relégué à la fin d'un projet, quand il conditionne la vitesse de feedback dès le premier jour. Ce chapitre traverse la chaîne complète : build, IDE, analyse statique, packaging et intégration continue, en gardant comme fil conducteur l'API de gestion d'abonnements du module.
Prérequis : avoir exécuté au moins une fois un projet Java (compilation manuelle ou via IDE) ; chapitre Qualité/tests pour les outils de test.
Objectifs : structurer un build multi-module avec Maven ou Gradle ; automatiser formatage et analyse statique ; packager un runtime sur mesure ; assembler une chaîne d'intégration continue.
#1. Maven ou Gradle
Les deux résolvent le même problème (dépendances, cycle de vie, plugins) avec des philosophies différentes :
- Maven : conventions fortes (
src/main/java,src/test/java), configuration déclarative en XML, cycle de vie standardisé (validate,compile,test,package,verify). Prévisible, ubiquitaire, verbeux. - Gradle : DSL Kotlin (ou Groovy), graphes de tâches incrémentaux, cache de build. Concis et rapide sur les gros projets, mais la liberté de configuration demande de la discipline d'équipe.
Même cas d'usage, un projet multi-module domain / app / infra : la règle de dépendance va du haut vers le bas (app et infra dépendent de domain, jamais l'inverse), ce qui garde le modèle métier libre de tout framework. En Maven, un parent porte la configuration commune et chaque module déclare son parent ; en Gradle, un settings.gradle.kts liste les modules inclus et le plugin java-library gère les dépendances.
1// settings.gradle.kts2rootProject.name = "abonnements"3include("domain", "app", "infra")#2. Verrouiller la qualité à chaque commit
Le build exécute plus que les tests. Trois familles d'outils s'installent tôt :
- Formatage :
spotless(Maven ou Gradle) applique palantir-java-format ou google-java-format ; un commit mal formaté casse le build plutôt que de polluer les revues. - Analyse statique : Checkstyle (style et conventions), SpotBugs (motifs de bugs détectés sur le bytecode), PMD (code suspect). Leur valeur vient de règles activées progressivement, pas d'un pack complet imposé d'un coup.
- Couverture et mutations : JaCoCo mesure la couverture, Pitest vérifie que les tests tuent les mutants (voir chapitre Qualité).
1// extrait build.gradle.kts2spotless {3 java { palantirJavaFormat() }4 kotlinGradle { ktlint() }5}#3. IDE et boucle de feedback courte
Côté IDE, IntelliJ IDEA domine pour Java : refactorings sûrs (renommage traversant, extraction), inspections à la volée, débogueur avec évaluation d'expression, intégration native des frameworks. VS Code avec l'extension pack Java offre une alternative légère, adaptée aux environnements pédagogiques et aux petites contributions.
Deux réglages qui changent le quotidien : le rechargement à chaud du serveur (spring-boot-devtools, quarkus:dev) pour voir les modifications sans redémarrage complet, et le profilage intégré (async-profiler via l'IDE ou un agent) pour partir de mesures plutôt que d'intuitions.
#4. Packaging et delivery
La JVM moderne permet de ne livrer que ce que l'application utilise :
jlinkassemble un runtime personnalisé ne contenant que les modules requis : image finale de quelques dizaines de mégaoctets au lieu d'un JDK complet.jpackageproduit un installateur natif (deb, rpm, msi, dmg) embarquant ce runtime.- Les images de conteneurs distroless (ou
jibcôté build) appliquent le même principe : pas de shell, pas de gestionnaire de paquets, surface d'attaque minimale.
Un point qui distingue Java des images traditionnelles : les virtual threads et le ramasse-miettes rendent inutile la multiplication des processus ; un conteneur, une application, la JVM gère la concurrence en interne.
#5. Intégration continue
La chaîne CI exécute, à chaque poussée, la séquence complète : compilation, tests, analyse statique, tests de mutation (sur les chemins modifiés), benchmarks JMH si des chemins chauds ont bougé, puis construction de l'image et déploiement sur l'environnement de recette. Exemple minimal GitHub Actions :
1name: ci2on: [push, pull_request]3jobs:4 build:5 runs-on: ubuntu-latest6 steps:7 - uses: actions/checkout@v48 - uses: actions/setup-java@v49 with: { distribution: temurin, java-version: '21', cache: gradle }10 - run: ./gradlew build11 - run: ./gradlew pitestLe cache de dépendances (cache: gradle) évite de retélécharger l'écosystème à chaque exécution ; c'est souvent la différence entre une CI de deux minutes et une CI de vingt.
#6. Atelier fil rouge
Assemblez la chaîne complète sur l'API d'abonnements : trois modules Gradle avec la règle de dépendance app/infra vers domain, Spotless et SpotBugs branchés sur check, image construite avec jib, workflow GitHub Actions exécutant build et Pitest à chaque poussée.
Vérification observable : ./gradlew check échoue si un fichier est mal formaté ou si SpotBugs remonte un motif ; la page Actions affiche le pipeline vert avec les trois modules compilés séparément.