Développement Java (Java pur)
Conseils au quotidien pour les projets Java qui ne sont pas liés à un framework. Si le projet utilise Spring Boot, Quarkus, Helidon ou similaire, privilégiez les skills du framework pour les préoccupations du framework et utilisez celui-ci pour les parties Java pur.
Règles qui s'appliquent toujours
- Détectez avant d'écrire. Lisez
pom.xml/build.gradle*,.mvn/,gradle/,.java-version/.sdkmanrc,.editorconfig, les fichiers CI et quelques fichiers source. Correspondez à l'outil de build, à la version Java, au formateur, au nommage, aux bibliothèques de logging et de test déjà en usage. - Ne mettez jamais à jour implicitement. Ne changez pas la version Java, la version de l'outil de build, les versions de plugin ou de dépendance, et n'ajoutez pas de formateur/linter/analyseur statique que le projet ne possède pas, comme effet secondaire d'une autre tâche. Suggérez-le et demandez. Les mises à niveau de version sont une tâche en soi (
java-upgrade, si installé). - Utilisez le wrapper (
./mvnw,./gradlew) s'il est présent ; sinon lemvn/gradleinstallé. Ne commitez pas un wrapper sans y être invité. - Vérifiez avec une build. Après tout changement, lancez la vérification propre au projet (
./mvnw -B verifyou./gradlew build) et signalez le résultat. Lancez une commande plus restrictive d'abord lors des itérations. Si vous n'avez pas pu la lancer, dites-le. - Demandez à l'utilisateur avant : de changer les API publiques ou les formats sérialisés/DB/wire, d'élever la version Java, d'ajouter des dépendances à l'exécution, d'ajouter des outils à la build, de supprimer ou affaiblir des tests, de changer la CI, ou quand deux conceptions raisonnables ont des compromis différents.
- Préférez la bibliothèque standard et le code petit et explicite aux nouvelles dépendances. Pas de Lombok sauf s'il est déjà utilisé.
Choisissez les idiomes selon la version Java du projet
Vérifiez maven.compiler.release/<release>, java.toolchain, ou sourceCompatibility ; n'utilisez jamais une fonctionnalité plus récente que cette version. Résumé (détails et extraits dans references/modern-java.md) :
| Version | Vous pouvez utiliser |
|---|---|
| 8 | lambdas, streams, Optional, java.time |
| 11 | var, String.isBlank/strip/lines, java.net.http.HttpClient, List.of/Map.of (9) |
| 17 | records, sealed classes, text blocks, switch expressions, patterns instanceof |
| 21 | pattern matching pour switch, record patterns, virtual threads, SequencedCollection (getFirst/getLast/reversed) |
| 22-24 | variables anonymes _ (22), Stream.gather (24) |
| 25 | scoped values, main d'instance/fichiers source compacts, déclarations d'import de module (tous finaux) |
La concurrence structurée (StructuredTaskScope) est toujours une API preview en 25 et 27 (vérifié : nécessite --enable-preview) ; ne l'utilisez pas dans du code production sauf si l'utilisateur accepte les fonctionnalités preview.
Outils de build en pratique
- Maven :
./mvnw -B verify(compile, tests unitaires, tests d'intégration, packaging),-pl <module> -ampour un module,dependency:tree,-DskipTestsseulement quand l'utilisateur le demande. Gradle :./gradlew build,test --tests 'pkg.Class',dependencies,dependencyInsight --dependency <name>. - Arborescence standard :
src/main/java,src/main/resources,src/test/java,src/test/resources; packager par fonctionnalité, un type top-level par fichier, pas de split packages. - Définissez explicitement la version Java (
maven.compiler.release/ Gradle toolchain avecoptions.release) et l'encodage UTF-8 ; ne vous fiez pas au JDK qui lance la build. - Wrapper, BOM et usage de
dependency:tree/versions:, version catalogs et multi-module layout :references/build-and-dependencies.md.
Dépendances et vulnérabilités
- Importez les BOMs (
junit-bom,testcontainers-bom, le BOM du framework) plutôt que de répéter les versions ; une version par bibliothèque dans tous les modules. - Inspectez avant de changer :
mvn dependency:tree -Dincludes=group:artifact/gradlew dependencyInsight. Résolvez les conflits avecdependencyManagementou les contraintes Gradle, pas en excluant au hasard. - Vérifiez les mises à jour avec
mvn versions:display-dependency-updates(ajoutez-Dmaven.version.ignorepour masquer alpha/beta/RC) et signalez-les ; n'appliquez pas de mises à niveau majeures sans demander. - Vulnérabilités : utilisez ce que le projet a (alertes Dependabot/Renovate, OWASP dependency-check, OSV-Scanner, GitHub dependency review). Suggérez-en un s'il n'en existe pas ; ne l'ajoutez pas silencieusement. Gardez les secrets hors de la config du scanner ; les scanners basés sur NVD ont besoin d'une clé API pour être pratiques.
Défaillances dépendantes de la version (vérifiées)
- JDK 23+ ne lance plus les annotation processors implicitement (Lombok, MapStruct, Dagger...) :
-proc:noneest le défaut sauf si-processor,--processor-pathou--processor-module-pathest fourni. Déclarez le chemin du processor dans la build (MavenannotationProcessorPaths, GradleannotationProcessor) ou passez-proc:full. JDK 21+ imprime un avertissement quand il détecte un usage implicite ;-proc:fullest aussi backporté à 17.0.11, 11.0.23 et 8u411. Source : https://inside.java/2024/06/18/quality-heads-up/. - Virtual threads et
synchronized: sur JDK 21-23 un virtual thread qui bloque à l'intérieur desynchronizedest épinglé à son carrier ; JEP 491 supprime presque tout ce pinning dans JDK 24+. Sur 21-23 préférezReentrantLockautour des appels bloquants. Source : https://openjdk.org/jeps/491. - Error Prone sur JDK 16+ a besoin des flags javac
--add-exports/--add-opens, et sur JDK 21-XDaddTypeAnnotationsToSymbol=true(voir la référence quality). - N'utilisez jamais une fonctionnalité du langage plus récente que la version du projet (voir le tableau ci-dessus).
Analyse statique et formatage (seulement si déjà présent, ou si l'utilisateur accepte)
Respectez ce qui est configuré : si le projet utilise Spotless/Checkstyle/SpotBugs/Error Prone, lancez-les et corrigez les trouvailles ; sinon, ne les ajoutez pas. Quand on vous demande de les introduire, commencez par -Xlint:all et Spotless (formateur uniquement), puis Error Prone. Les configs vérifiées pour Maven et Gradle sur JDK 21 et 25 (incluant l'exigence -XDaddTypeAnnotationsToSymbol=true pour JDK 21 uniquement et les flags .mvn/jvm.config de Maven) sont dans references/quality-and-packaging.md. Ne reformatez jamais la base de code entière dans un changement sans lien.
Packaging et CI
- Bibliothèque jar simple :
mvn package/gradlew jar. App exécutable : shaded/fat jar ou répertoirelib/plus manifestMain-Class; runtime personnalisé avecjlink; installateur natif/app-image avecjpackage(vérifié sur macOS, voirreferences/quality-and-packaging.md). - GitHub Actions :
actions/checkout,actions/setup-javaavecdistribution: temurin, unejava-versionexplicite,cachedépendance intégrée, puis./mvnw -B verifyou./gradlew build. Extrait et notes dansreferences/quality-and-packaging.md. Ne changez pas la CI sans demander.
Skills connexes (utilisez quand installés)
java-junit (tests unitaires), java-testcontainers (tests d'intégration avec Docker), java-hibernate-jpa (persistance), java-debugging (défaillances et stack traces), java-diagnostics (performance, mémoire, threads, JFR), java-upgrade (mises à niveau JDK/framework), lsp-setup (serveur de langage Java pour navigation et refactoring).
Références
references/modern-java.md: idiomes et extraits vérifiés (records, types sealed, switch patterns, text blocks, virtual threads,SequencedCollection, variables anonymes), statut preview, pièges.references/build-and-dependencies.md: commandes Maven/Gradle, wrappers, BOMs, diagnostic de conflit, vérification de mise à jour, Dependabot/Renovate, scan de vulnérabilités.references/quality-and-packaging.md: setup de logging,-Xlint, Spotless, Error Prone, notes Checkstyle/SpotBugs, jar/jlink/jpackage, GitHub Actions.