Communitygithub.com

normes-de-codage-java

Normes de codage Java pour les services Spring Boot et Quarkus : nommage, immutabilité, utilisation d'Optional, streams, exceptions, génériques, CDI, patterns réactifs et structure de projet. Applique automatiquement les conventions spécifiques au framework. À utiliser lors de l'écriture ou de la relecture de code Java dans un service Spring Boot ou Quarkus.

Qu'est-ce que normes-de-codage-java ?

Cette compétence établit des normes de codage Java (17+) pour les services Spring Boot et Quarkus, garantissant un code lisible, maintenable et cohérent. Elle détecte automatiquement le framework utilisé (le fichier de construction contient 'quarkus' ou 'spring-boot') et applique les conventions correspondantes. Les principes incluent l'immutabilité par défaut, l'échec rapide avec des exceptions significatives, et un nommage cohérent. Les sections couvrent le nommage, l'immutabilité, l'utilisation d'Optional, les streams, l'injection de dépendances, les patterns réactifs, les exceptions, les génériques, la structure de projet, le formatage, les anti-patrons, la journalisation, la gestion des nulls, la configuration et les tests, avec des exemples concrets pour Spring Boot et Quarkus.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/tree/main/skills/java-coding-standards

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Normes de Codage Java

Normes pour un code Java (17+) lisible et maintenable dans les services Spring Boot et Quarkus.

Quand l'utiliser

  • Écrire ou relire du code Java dans des projets Spring Boot ou Quarkus
  • Appliquer des conventions de nommage, d'immutabilité ou de gestion des exceptions
  • Travailler avec des records, des classes sealed ou du pattern matching (Java 17+)
  • Réviser l'utilisation d'Optional, des streams ou des génériques
  • Structurer les packages et la disposition du projet
  • [QUARKUS] : Travailler avec les portées CDI, les entités Panache ou les pipelines réactifs

Comment ça fonctionne

Détection du Framework

Avant d'appliquer les normes, déterminer le framework à partir du fichier de construction :

  • Le fichier de construction contient quarkus → appliquer les conventions [QUARKUS]
  • Le fichier de construction contient spring-boot → appliquer les conventions [SPRING]
  • Aucun détecté → appliquer uniquement les conventions partagées

Principes Fondamentaux

  • Privilégier la clarté à l'ingéniosité
  • Immutable par défaut ; minimiser l'état mutable partagé
  • Échouer rapidement avec des exceptions significatives
  • Nommage et structure de package cohérents
  • [QUARKUS] : Favoriser le traitement à la construction plutôt qu'à l'exécution ; éviter la réflexion à l'exécution lorsque possible

Exemples

Les sections ci-dessous montrent des exemples concrets pour Spring Boot, Quarkus, et des exemples Java partagés pour le nommage, l'immutabilité, l'injection de dépendances, le code réactif, les exceptions, la disposition du projet, la journalisation, la configuration et les tests.

Nommage

// PASS : Classes/Records : PascalCase
public class MarketService {}
public record Money(BigDecimal amount, Currency currency) {}

// PASS : Méthodes/champs : camelCase
private final MarketRepository marketRepository;
public Market findBySlug(String slug) {}

// PASS : Constantes : UPPER_SNAKE_CASE
private static final int MAX_PAGE_SIZE = 100;

// PASS : [QUARKUS] Ressources JAX-RS nommées *Resource, pas *Controller
public class MarketResource {}

// PASS : [SPRING] Contrôleurs REST nommés *Controller
public class MarketController {}

Immutabilité

// PASS : Privilégier les records et les champs finaux
public record MarketDto(Long id, String name, MarketStatus status) {}

public class Market {
  private final Long id;
  private final String name;
  // uniquement des getters, pas de setters
}

// PASS : [QUARKUS] Les entités Panache active-record utilisent des champs publics (convention Quarkus)
@Entity
public class Market extends PanacheEntity {
  public String name;
  public MarketStatus status;
  // Panache génère les accesseurs à la construction ; les champs publics sont idiomatiques ici
}

// PASS : [QUARKUS] Entités MongoDB Panache
@MongoEntity(collection = "markets")
public class Market extends PanacheMongoEntity {
  public String name;
  public MarketStatus status;
}

Utilisation d'Optional

// PASS : Retourner Optional depuis les méthodes find*
// [SPRING]
Optional<Market> market = marketRepository.findBySlug(slug);

// [QUARKUS] Panache
Optional<Market> market = Market.find("slug", slug).firstResultOptional();

// PASS : Utiliser map/flatMap au lieu de get()
return market
    .map(MarketResponse::from)
    .orElseThrow(() -> new EntityNotFoundException("Marché non trouvé"));

Bonnes pratiques avec les Streams

// PASS : Utiliser les streams pour les transformations, garder les pipelines courts
List<String> names = markets.stream()
    .map(Market::name)
    .filter(Objects::nonNull)
    .toList();

// FAIL : Éviter les streams imbriqués complexes ; préférer les boucles pour la clarté

Injection de Dépendances

// PASS : [SPRING] Injection par constructeur (préférée à @Autowired sur les champs)
@Service
public class MarketService {
  private final MarketRepository marketRepository;

  public MarketService(MarketRepository marketRepository) {
    this.marketRepository = marketRepository;
  }
}

// PASS : [QUARKUS] Injection par constructeur
@ApplicationScoped
public class MarketService {
  private final MarketRepository marketRepository;

  @Inject
  public MarketService(MarketRepository marketRepository) {
    this.marketRepository = marketRepository;
  }
}

// PASS : [QUARKUS] Injection de champ package-private (acceptable dans Quarkus — évite les problèmes de proxy)
@ApplicationScoped
public class MarketService {
  @Inject
  MarketRepository marketRepository;
}

// FAIL : [SPRING] Injection de champ avec @Autowired
@Autowired
private MarketRepository marketRepository; // utiliser l'injection par constructeur

// FAIL : [QUARKUS] @Singleton quand l'interception ou l'initialisation différée est nécessaire
@Singleton // non-proxyable — utiliser @ApplicationScoped à la place
public class MarketService {}

Patterns Réactifs [QUARKUS]

// PASS : Retourner Uni/Multi depuis les endpoints réactifs
@GET
@Path("/{slug}")
public Uni<Market> findBySlug(@PathParam("slug") String slug) {
  return Market.find("slug", slug)
      .<Market>firstResult()
      .onItem().ifNull().failWith(() -> new MarketNotFoundException(slug));
}

// PASS : Composition de pipeline non bloquante
public Uni<OrderConfirmation> placeOrder(OrderRequest req) {
  return validateOrder(req)
      .chain(valid -> persistOrder(valid))
      .chain(order -> notifyFulfillment(order));
}

// FAIL : Appel bloquant dans un pipeline Uni/Multi
public Uni<Market> find(String slug) {
  Market m = Market.find("slug", slug).firstResult(); // BLOQUANT — casse la boucle d'événements
  return Uni.createFrom().item(m);
}

// FAIL : S'abonner plus d'une fois à un Uni partagé
Uni<Market> shared = fetchMarket(slug);
shared.subscribe().with(m -> log(m));
shared.subscribe().with(m -> cache(m)); // double abonnement — utiliser Uni.memoize()

Exceptions

  • Utiliser des exceptions non vérifiées pour les erreurs métier ; envelopper les exceptions techniques avec du contexte
  • Créer des exceptions spécifiques au domaine (par exemple, MarketNotFoundException)
  • Éviter les catch (Exception ex) larges sauf pour relancer ou journaliser centralement
throw new MarketNotFoundException(slug);

Gestion Centralisée des Exceptions

// [SPRING]
@RestControllerAdvice
public class GlobalExceptionHandler {
  @ExceptionHandler(MarketNotFoundException.class)
  public ResponseEntity<ErrorResponse> handle(MarketNotFoundException ex) {
    return ResponseEntity.status(404).body(ErrorResponse.from(ex));
  }
}

// [QUARKUS] Option A : ExceptionMapper
@Provider
public class MarketNotFoundMapper implements ExceptionMapper<MarketNotFoundException> {
  @Override
  public Response toResponse(MarketNotFoundException ex) {
    return Response.status(404).entity(ErrorResponse.from(ex)).build();
  }
}

// [QUARKUS] Option B : @ServerExceptionMapper (RESTEasy Reactive)
@ServerExceptionMapper
public RestResponse<ErrorResponse> handle(MarketNotFoundException ex) {
  return RestResponse.status(Status.NOT_FOUND, ErrorResponse.from(ex));
}

Génériques et Sécurité des Types

  • Éviter les types bruts ; déclarer des paramètres génériques
  • Privilégier les génériques bornés pour les utilitaires réutilisables
public <T extends Identifiable> Map<Long, T> indexById(Collection<T> items) { ... }

Structure du Projet

[SPRING] Maven/Gradle

src/main/java/com/example/app/
  config/
  controller/
  service/
  repository/
  domain/
  dto/
  util/
src/main/resources/
  application.yml
src/test/java/... (miroir de main)

[QUARKUS] Maven/Gradle

src/main/java/com/example/app/
  config/              # @ConfigMapping, beans @ConfigProperty, Producers
  resource/            # Ressources JAX-RS (pas "controller")
  service/
  repository/          # Implémentations PanacheRepository (si on n'utilise pas active record)
  domain/              # Entités JPA/Panache, entités MongoDB
  dto/
  util/
  mapper/              # Mappers MapStruct (si utilisés)
src/main/resources/
  application.properties   # Convention Quarkus (YAML supporté avec quarkus-config-yaml)
  import.sql               # Import automatique Hibernate pour dev/test
src/test/java/... (miroir de main)

Formatage et Style

  • Utiliser 2 ou 4 espaces de manière cohérente (standard du projet)
  • Un seul type public de premier niveau par fichier
  • Garder les méthodes courtes et ciblées ; extraire des méthodes d'aide
  • Ordre des membres : constantes, champs, constructeurs, méthodes publiques, protégées, privées

Anti-patrons à Éviter

  • Listes de paramètres longues → utiliser des DTO/builders
  • Imbrication profonde → retours précoces
  • Nombres magiques → constantes nommées
  • État mutable statique → préférer l'injection de dépendances
  • Blocs catch silencieux → journaliser et agir ou relancer
  • [QUARKUS] : @Singleton là où @ApplicationScoped est prévu — casse le proxying et l'interception
  • [QUARKUS] : Mélanger quarkus-resteasy-reactive et quarkus-resteasy (classique) — choisir une pile
  • [QUARKUS] : Panache active-record + pattern repository dans le même contexte délimité — en choisir un

Journalisation

// [SPRING] SLF4J
private static final Logger log = LoggerFactory.getLogger(MarketService.class);
log.info("fetch_market slug={}", slug);
log.error("failed_fetch_market slug={}", slug, ex);

// [QUARKUS] JBoss Logging (par défaut, coût nul à la construction)
private static final Logger log = Logger.getLogger(MarketService.class);
log.infof("fetch_market slug=%s", slug);
log.errorf(ex, "failed_fetch_market slug=%s", slug);

// [QUARKUS] Alternative : journalisation simplifiée avec @Inject
@Inject
Logger log; // injecté par CDI, délimité par la classe déclarante

Gestion des Nulls

  • Accepter @Nullable uniquement lorsque c'est inévitable ; sinon utiliser @NonNull
  • Utiliser Bean Validation (@NotNull, @NotBlank) sur les entrées
  • [QUARKUS] : Appliquer @Valid sur @BeanParam, @RestForm, et les paramètres du corps de la requête

Configuration

// [SPRING] @ConfigurationProperties
@ConfigurationProperties(prefix = "market")
public record MarketProperties(int maxPageSize, Duration cacheTtl) {}

// [QUARKUS] @ConfigMapping (type-safe, validé à la construction)
@ConfigMapping(prefix = "market")
public interface MarketConfig {
  int maxPageSize();
  Duration cacheTtl();
}

// [QUARKUS] Valeurs simples avec @ConfigProperty
@ConfigProperty(name = "market.max-page-size", defaultValue = "100")
int maxPageSize;

Attentes pour les Tests

Partagé

  • JUnit 5 + AssertJ pour des assertions fluides
  • Mockito pour le mocking ; éviter les mocks partiels lorsque possible
  • Privilégier les tests déterministes ; pas de sleep cachés

[SPRING]

  • @WebMvcTest pour les tests de contrôleurs, @DataJpaTest pour les tests de repositories
  • @SpringBootTest réservé aux tests d'intégration complets
  • @MockBean pour remplacer des beans dans le contexte Spring

[QUARKUS]

  • JUnit 5 + Mockito pour les tests unitaires (pas de @QuarkusTest)
  • @QuarkusTest réservé aux tests d'intégration CDI
  • @InjectMock pour remplacer les beans CDI dans les tests d'intégration
  • Dev Services pour la base de données/Kafka/Redis — éviter la configuration manuelle de Testcontainers quand Dev Services suffit
  • @QuarkusTestResource pour le cycle de vie personnalisé des services externes
// [SPRING] Test de contrôleur
@WebMvcTest(MarketController.class)
class MarketControllerTest {
  @Autowired MockMvc mockMvc;
  @MockBean MarketService marketService;
}

// [QUARKUS] Test d'intégration
@QuarkusTest
class MarketResourceTest {
  @InjectMock
  MarketService marketService;

  @Test
  void should_return_404_when_market_not_found() {
    given().when().get("/markets/unknown").then().statusCode(404);
  }
}

// [QUARKUS] Test unitaire (pas de CDI, pas de @QuarkusTest)
@ExtendWith(MockitoExtension.class)
class MarketServiceTest {
  @Mock MarketRepository marketRepository;
  @InjectMocks MarketService marketService;
}

Rappelez-vous : Gardez le code intentionnel, typé et observable. Optimisez pour la maintenabilité plutôt que pour les micro-optimisations, sauf si elles sont nécessaires.

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

Skills associés