Software engineer reviewing Java code, security controls, and observability dashboards on multiple monitors during a Spring Boot migration.

Spring Boot 4.1 Is Available: Upgrade a 3.x Service Without Breaking Modules, Security, or Observability

Mon, Sep 7, 2026

Un service passe de Spring Boot 3.x à 4.1.1. Maven compile. Les tests unitaires sont verts. L’image démarre. Pourtant, une route d’administration qui exigeait auparavant l’autorité pricing:write accepte désormais n’importe quel utilisateur authentifié. En parallèle, le compteur qui alimente le tableau de bord du processus de commande n’est plus exporté. Rien de cela n’apparaît dans le résultat de mvn test.

C’est le scénario que cette migration doit empêcher. Le Spring Blog, dans « Spring Boot 4.1.1 available now » du 20 août 2026, annonce 98 corrections, des améliorations de documentation et des mises à niveau de dépendances. C’est une bonne raison de suivre la ligne maintenue, mais pas une preuve que votre application reste opérationnellement équivalente.

Après plus de quatorze ans à raisonner sur des services Java en production, je considère la compilation comme un premier contrôle, pas comme un verdict de migration. Une Spring Boot 4.1 migration doit démontrer l’équivalence sur cinq surfaces : résolution du build et des dépendances, comportement applicatif, politique de sécurité, télémétrie, puis packaging et exécution.

Ce Spring Boot 4 migration guide part donc d’un état 3.x exact, construit des preuves avant modification, traverse explicitement les frontières Spring Boot 4 et Spring Framework 7, puis exige des tests d’intégration, un canary et un rollback répété. C’est cette discipline qui transforme un Spring Boot 3 to 4 upgrade en changement de production contrôlable.

Define the Exact Spring Boot 3.x-to-4.1 Migration Boundary

La première décision n’est pas « passer à Boot 4 ». Elle est : de quelle version exacte partons-nous, et vers quelle version exacte allons-nous ? Pour le service témoin de ce guide, je fixe la source à Spring Boot 3.5.16, Spring Framework 6.2.19, Spring Security 6.5.11 et Java 17. La cible est Spring Boot 4.1.1, Spring Framework 7.0.9, Spring Security 7.1.1 et Java 21. La documentation Spring affichait encore 3.5.16 et 4.1.1 parmi les lignes stables au 7 septembre 2026.

La documentation officielle « Upgrading Spring Boot » demande aux équipes qui sautent des versions de lire les notes de chaque version franchie. Le Spring Boot 4.0 Migration Guide recommande en outre aux utilisateurs 3.x de rejoindre d’abord la dernière 3.5.x et de traiter les API dépréciées avant de passer à 4.0.

Décision de frontière

Valeur du service témoin

Preuve exigée

Baseline Boot

3.5.16

Build et artefact de référence archivés

Runtime initial

Java 17

Tests + profil de performance

Étape préparatoire

Boot 3.5.16 sur Java 21

Qualification indépendante

Cible

Boot 4.1.1 / Framework 7.0.9

Tous les gates de parité

Fenêtres traversées

3.5 → 4.0 → 4.1

Notes de migration signées

Rollback

artefact 3.5.16 connu bon

retour de trafic répété

Spring indique que les versions majeures bénéficient d’au moins trois ans de support, à condition d’utiliser une version mineure supportée, tandis que les versions mineures sont supportées au moins douze mois. Cela doit alimenter la décision de calendrier, pas remplacer votre politique interne de patching.

Cette page ne choisit pas Spring Boot face à une autre pile. Le sujet « framework » appartient plutôt à la comparaison Node.js, Django, and Spring Boot frameworks ou au panorama des modern full-stack frameworks. Ici, la décision est déjà prise : nous devons déplacer un service Spring existant sans perdre ses propriétés de production.

Gate de promotion : aucun changement Boot 4 ne commence tant que source, cible, versions intermédiaires, propriétaire technique, fenêtre de changement et artefact de rollback ne sont pas écrits dans le dossier de migration.

Inventory Dependencies, Auto-Configuration, Java, and Runtime Packaging

Le BOM (Bill of Materials, catalogue de versions gérées) est un mécanisme de cohérence, pas une attestation universelle de compatibilité. Il ne sait pas que votre agent APM, votre starter interne, votre proxy, votre plugin de génération de code ou votre plateforme managée accepte effectivement les versions qu’il sélectionne.

Je demande donc un inventaire reproductible issu du build effectif, et non une lecture manuelle du pom.xml. Capturez dependency:tree, les dépendances résolues, les plugins, les BOM importés, les exclusions et overrides, puis associez chaque composant à un propriétaire et à un test.

Champ d’inventaire

Exemple de donnée à enregistrer

Service / owner

pricing-api / équipe responsable

Boot / Framework / Java

3.5.16 / 6.2.19 / 17

BOM additionnels

Spring Cloud, SDK cloud, BOM interne

Overrides

coordonnées + raison + ticket d’expiration

Starters

web, security, actuator, data-jpa, kafka

Auto-config custom

nom du module + conditions

Data / messaging

PostgreSQL, Flyway, Kafka, cache

Servlet / HTTP

Tomcat, clients, proxy/ingress

Agents

APM, profiler, sécurité

Build

Maven/Gradle, compilateur, processors

Packaging

JAR, OCI, AOT, native

Plateforme

orchestrateur, architecture CPU, secrets

Rollback

digest de l’artefact et contraintes data

Pour le contexte API et microservices, l’API developer roadmap from HTTP to microservices couvre la vue plus générale ; l’inventaire ici sert uniquement à rendre une migration versionnée auditable.

Map BOM Overrides, Starters, and Third-Party Integrations

Le différentiel de versions est un artefact de revue, pas une annexe décorative. Pour notre service témoin, les versions gérées montrent notamment :

Composant

Boot 3.5.16

Boot 4.1.1

Spring Framework

6.2.19

7.0.9

Spring Security

6.5.11

7.1.1

Tomcat

10.1.55

11.0.24

Hibernate ORM

6.6.53.Final

7.4.5.Final

Flyway

11.7.2

12.4.0

Spring Kafka

3.3.16

4.1.1

PostgreSQL JDBC

42.7.11

42.7.13

Micrometer

1.15.12

1.17.1

OpenTelemetry

1.49.0

1.62.0

Testcontainers

1.21.4

2.0.5

Ces valeurs proviennent des catalogues gérés de Boot 3.5.16 et des managed dependency versions de Spring Boot 4.1.1. Elles démontrent l’ampleur du déplacement transitif : Hibernate, Flyway, Kafka, Micrometer et Testcontainers franchissent tous une frontière significative. Elles ne démontrent pas que vos mappings JPA, migrations SQL, sérialiseurs Kafka ou extensions Testcontainers sont compatibles.

Record Java, Build, Container, and Platform Constraints

Pour chaque environnement, enregistrez également le JDK exact, l’architecture CPU, le mode CDS éventuel, les flags JVM, la version Maven/Gradle, l’image de build, l’image runtime, le digest OCI, le noyau/container runtime pertinent et les limites CPU/mémoire.

Le propriétaire plateforme bloque la migration lorsqu’une dépendance ne possède pas de matrice de support vérifiable. Un cas concret de divergence est jOOQ : Boot 4.1.1 exige globalement Java 17 minimum, mais les notes 4.1 indiquent que la génération jOOQ 3.20 gérée requiert Java 21. Une application jOOQ a donc une exigence effective plus élevée que le minimum de Boot.

Freeze Functional, Security, and Observability Baselines

Une migration sans baseline transforme tout écart en débat. Avant de changer Java, Maven ou le BOM, capturez ce que signifie « correct » en Boot 3.5.16. Le résultat n’est pas seulement un ensemble de tests : c’est une fiche de parité exécutable.

Pour le comportement, rejouez les opérations métier représentatives : lectures, mutations, validations négatives, transactions, batchs et jobs planifiés. Pour les dépendances, testez contre les vraies versions de PostgreSQL, Kafka, cache et API aval utilisées en préproduction. En production-like, collectez démarrage, mémoire, CPU, latences p50/p95/p99 et taux d’erreur sous une charge reproductible.

Surface

Baseline à figer

Critère de comparaison

API

statuts, corps, headers, erreurs

contrat inchangé ou changement approuvé

Jobs

cadence, lock, résultat

pas de doublon/perte

Persistence

SQL, transactions, migrations

données et isolation équivalentes

Messaging

clés, headers, schémas, retries

compatibilité producteur/consommateur

Security

2xx/401/403, rôles, headers

matrice identique

Metrics

noms, tags, unités, cardinalité

dashboard et alertes alimentés

Traces

propagation et attributs

corrélation bout en bout

Logs

champs, niveaux, corrélation

requêtes opérables

Health

groupes et détails

même signification opérationnelle

Runtime

mémoire, latence, démarrage

budget défini avant migration

Le point de sécurité est souvent sous-baseliné. Enregistrez non seulement qu’un utilisateur autorisé obtient 200, mais qu’un token expiré obtient 401, qu’un utilisateur authentifié sans droit obtient 403, que les en-têtes de sécurité attendus sont présents et que les endpoints Actuator ne sont pas accessibles depuis le mauvais réseau.

Même discipline pour l’observabilité : prenez un scrape Prometheus de référence, une trace distribuée représentative et un log corrélé au trace ID. Spring Actuator offre des fonctionnalités de health, metrics et management, mais la présence de /actuator/health ne prouve pas qu’un tableau de bord reçoit encore la même série temporelle.

Gate de promotion : chaque entrée critique doit avoir un test ou une procédure de comparaison propriétaire. Une métrique critique « connue par l’équipe » mais non capturée est une dette bloquante.

Upgrade Java and Build Tooling as Independent Changes

Ne changez pas le JDK, le moteur de build et Spring Boot dans le même commit. Sinon, un échec d’annotation processor, une différence de bytecode ou un plugin incompatible arrive dans le même lot qu’un changement de Framework 7.

Les Spring Boot 4.1.1 system requirements donnent Java 17 minimum, avec support jusqu’à Java 26, Spring Framework 7.0.9 ou ultérieur, Maven 3.6.3+, Gradle 8.14+ sur la ligne 8.x et Gradle 9.x.

Dans notre service témoin, je fais d’abord tourner Boot 3.5.16 sur Java 21. Cela qualifie séparément le runtime souhaité. Ensuite seulement, je change Boot. Même principe pour Maven : Apache Maven a publié 3.9.16 le 30 août 2026, et le présente désormais comme la version 3.x recommandée. Re-vérifier la version retenue avant la migration évite de figer une recommandation devenue obsolète.

Create and Test the Supported Version Matrix

Étape

Boot

Java

Build

Ce qu’elle isole

A

3.5.16

17

Maven 3.9.15

baseline

B

3.5.16

21

Maven 3.9.15

JDK uniquement

C

3.5.16

21

Maven 3.9.16

build uniquement

D

4.1.1

21

Maven 3.9.16

framework

E

4.1.1

21

même CI

image de production

À chaque ligne, compilez avec les mêmes --release, toolchains, annotation processors, paramètres de test et règles de reproductibilité. Vérifiez Surefire/Failsafe, JaCoCo, Checkstyle/SpotBugs, génération OpenAPI ou protobuf, Lombok/MapStruct, plugins de packaging et publication. Inspectez également le bytecode ou au minimum la version de classe générée lorsqu’une autre équipe consomme vos bibliothèques.

La CI doit utiliser une image de build épinglée, pas simplement maven:latest. Comparez le hash de l’artefact entre deux builds identiques lorsque la reproductibilité est un objectif de supply chain.

La discussion générale sur l’outillage de développement peut vivre dans IDEs for API developers ; ici, l’IDE n’est jamais l’autorité. L’autorité est la toolchain CI reproductible.

Stop condition : si B ou C casse, corrigez cette étape avant Boot 4. Un rollback du framework ne résoudra pas un problème introduit par un JDK ou plugin changé simultanément.

Migrate Boot 4 and Spring Framework 7 Modules Deliberately

Boot 4 n’est pas seulement « Boot 3 avec des versions plus récentes ». Le Spring Boot 4.0 Migration Guide décrit une modularisation visant des modules plus petits et ciblés, avec des starters plus cohérents. Les applications qui dépendaient directement de modules Boot plutôt que des starters doivent donc revoir leurs dépendances. Les infrastructures de test sont elles aussi davantage modularisées.

Le guide signale aussi la suppression des API dépréciées de la génération 3.x et demande de comparer la gestion de dépendances 3.5/4.0 avant migration. Spring Framework 7 conserve Java 17 comme baseline tout en basculant sur la génération Jakarta EE 11 et apporte notamment JSpecify pour la null-safety.

Zone

Action de migration

Starters web

vérifier les renommages, dont l’orientation vers spring-boot-starter-webmvc

Database migrations

ajouter les starters Flyway/Liquibase appropriés si nécessaire

Tests

inventorier explicitement les modules/test starters réellement utilisés

Auto-config interne

recompiler, tester les conditions et metadata

API dépréciées

supprimer avant ou pendant la frontière 4.0

JSON

qualifier Jackson 3, plus seulement Jackson 2

Retry

vérifier l’usage de Spring Retry et la stratégie de remplacement

Portfolio Spring

lire les release notes Security/Data/Kafka/Integration/etc.

La migration JSON mérite un gate dédié. Boot 4 préfère Jackson 3 ; le guide de migration documente le déplacement principal de packages de com.fasterxml.jackson vers tools.jackson, tout en conservant les annotations dans leur espace existant. Boot peut encore travailler avec Jackson 2 via des mécanismes de compatibilité, mais ce sont des ponts de migration, pas une raison de reporter indéfiniment l’inventaire des sérialiseurs.

Pour chaque auto-configuration interne, exigez un test ApplicationContextRunner ou équivalent Boot 4, plus un test où sa condition doit être fausse. Une auto-configuration absente silencieusement est souvent plus dangereuse qu’une application qui refuse de démarrer.

Gate : pas de « classic starter » ou pont Jackson conservé sans ticket d’élimination, responsable et date. Les aides de migration doivent être visibles dans la dette de sortie.

Qualify Jakarta, Servlet, Container, and Dependency Boundaries

Spring Boot 4.1.1 cible une génération différente de l’environnement servlet : la documentation système liste Tomcat 11.0.x et Jetty 12.1.x, tous deux sur Servlet 6.1, et indique qu’un déploiement WAR peut viser un conteneur compatible Servlet 6.1 ou supérieur. Le BOM 4.1.1 gère actuellement Tomcat 11.0.24.

Cette frontière doit être traitée comme une modification protocolaire et de conteneur. Rejouez les filtres, listeners, dispatch ERROR/ASYNC, uploads multipart, encodages, cookies, timeouts, taille d’en-têtes, compression, WebSocket si utilisé et comportement derrière le proxy. Vérifiez également toute bibliothèque qui compile contre jakarta.servlet, jakarta.validation, JPA ou autres API Jakarta.

Un changement particulièrement explicite de Boot 4 est la suppression du support Undertow, le guide de migration indiquant son incompatibilité avec le niveau Servlet 6.1 requis. Une organisation standardisée sur Undertow doit donc prendre une décision de conteneur avant la migration, et non découvrir cette frontière dans la dernière semaine.

Test Embedded Servers and External Deployment Targets

Test de frontière

Embedded Tomcat

WAR externe

Critère

/error après exception

oui

oui

statut/body/headers attendus

Forwarded headers

derrière proxy

derrière proxy

schéma/host client corrects

Filter order

introspection + trafic

même contrôle

ordre documenté

Multipart

taille limite réelle

idem

succès et refus corrects

Session/cookie

navigateur/client réel

idem

attributs identiques

Async requests

charge/timeout

idem

pas de fuite ni timeout surprise

HTTP/2/TLS

chemin plateforme

chemin plateforme

handshake et protocoles attendus

Le propriétaire runtime doit aussi tester l’agent Java et les bibliothèques natives éventuelles avec Tomcat 11. « L’agent s’injecte » n’est pas suffisant : comparez instrumentations, overhead et erreurs de transformation de classes.

Pour les clients HTTP sortants, qualifiez DNS, proxy système, mTLS (mutual TLS, authentification mutuelle par certificat), connection pooling et redirections. Les release notes 4.1 mentionnent notamment des évolutions des builders Reactor HTTP et des protections liées à la résolution d’adresses ; une application WebFlux mérite donc ses propres tests réseau.

Rollback : gardez l’image 3.5.16 et sa configuration de routage intactes. Un rollback qui exige simultanément de reconfigurer l’ingress et de restaurer une image de conteneur n’a pas été suffisamment simplifié.

Re-Prove Authentication, Authorization, and Security Headers

La sécurité doit être testée comme une politique, pas comme un bean. Spring Security 7.1.1 est la ligne gérée par Boot 4.1.1. Sa documentation distingue clairement le securityMatcher, qui décide si une SecurityFilterChain s’applique, des requestMatchers, qui choisissent les règles d’autorisation à l’intérieur de cette chaîne. Cette nuance suffit à justifier des tests de chemins réels après toute refactorisation.

L’artefact minimum est une matrice négative et positive :

Surface

Cas autorisé

Cas refusé

Preuve

JWT API

claim correct

claim absent/incorrect

2xx vs 403

Sans token

Sans objet

requête anonyme

401

Admin

autorité admin

utilisateur standard

403

Method security

rôle métier

appel direct sans rôle

exception/refus

CSRF

token valide

absent/invalide

refus attendu

CORS

origin autorisée

origin interdite

headers/refus

Session

cookie valide

fixation/expiration

rotation/refus

Actuator

réseau/rôle ops

client applicatif

refus

Headers

réponse normale

erreur/redirect

headers présents

Exemple travaillé. Le service hypothétique pricing-api sur Boot 3.5.16 possède deux modules internes : platform-security-autoconfigure et platform-observability-autoconfigure. Le premier fournit la règle stricte sur /api/admin/reprice/**. Lors du travail de modularisation Boot 4, l’équipe remplace un starter agrégateur interne par des dépendances plus ciblées mais oublie le module de sécurité. L’application compile parce que le code métier n’importe aucune classe de ce module. Les tests unitaires des contrôleurs mockent le service et ne démarrent pas la vraie chaîne Spring Security.

La chaîne applicative restante contient une règle générique :

http
    .securityMatcher("/api/**")
    .authorizeHttpRequests(auth -> auth
        .anyRequest().authenticated());

Le POST /api/admin/reprice/42 devient donc accessible à un utilisateur authentifié ne possédant que pricing:read. Ce n’est pas présenté comme un changement de défaut de Boot 4 : c’est une erreur de composition de dépendances que la migration a rendue possible.

Un test d’intégration full-stack doit matérialiser la politique :

// Avec un utilisateur authentifié mais sans pricing:write
POST /api/admin/reprice/42
Expected: 403

Sur le candidat fautif, le test retourne 200 et bloque la promotion. Le correctif réintroduit explicitement la configuration qui exige pricing:write, puis le test couvre également utilisateur anonyme, autorité correcte, CSRF selon l’architecture, headers et accès management.

Cette approche constitue le cœur du Spring Boot security regression testing : tester les décisions d’autorisation observables et les chemins de refus, pas seulement l’existence d’un SecurityFilterChain.

Diff Configuration, Conditions, and Auto-Configuration Outcomes

Deux applications peuvent avoir le même application.yml et construire des contextes différents. Les causes typiques sont une propriété renommée, une variable d’environnement qui ne bind plus comme prévu, une classe absente du classpath, une condition qui change de résultat ou un bean utilisateur qui modifie le back-off d’une auto-configuration.

La documentation Spring Boot sur l’upgrade recommande temporairement spring-boot-properties-migrator pour diagnostiquer les propriétés renommées ou supprimées. Elle précise aussi une limite : les propriétés ajoutées tardivement via @PropertySource ne sont pas prises en compte par ce mécanisme. Le migrator doit être retiré après la migration.

La bonne comparaison porte sur l’état effectif :

Élément

Boot 3.5.16

Boot 4.1.1

Décision

propriétés résolues

export redacted

export redacted

diff approuvé

profils

liste active

liste active

identique

beans critiques

graphe

graphe

ajout/suppression expliqué

auto-config

matched/not matched

idem

écarts revus

customizers

liste/ordre

liste/ordre

comportement vérifié

failures

analyseurs connus

candidats

tests négatifs

Use Condition Reports and Configuration Metadata

Dans un environnement de test sans secrets réels, démarrez les deux versions avec le même jeu de variables, profils et fichiers de configuration. Capturez le rapport d’évaluation des conditions et normalisez les différences non déterministes. Cherchez en priorité les auto-configurations qui passent de « matched » à « did not match », ou l’inverse.

Testez explicitement les configurations facultatives : Kafka absent, base indisponible, exporter OTLP désactivé, profil batch, management port séparé, feature flag faux. Les bugs de condition n’apparaissent souvent que dans un profil secondaire.

Pour chaque propriété custom, générez et versionnez les metadata de configuration. Une propriété retirée doit échouer ou être détectée, pas être silencieusement oubliée.

Gate : tout écart de bean ou condition sur security, persistence, messaging, web, observability ou management doit être classé « attendu » avec une preuve, ou « régression » avec un correctif. Une différence inexpliquée suffit à arrêter la release.

Preserve Metrics, Traces, Logs, Health, and Management Access

Une Spring Boot observability migration doit vérifier les sémantiques de télémétrie. Boot 4.1.1 gère notamment Micrometer 1.17.1 et OpenTelemetry 1.62.0, contre Micrometer 1.15.12 et OpenTelemetry 1.49.0 dans le baseline 3.5.16 de notre service témoin. Ce sont des changements de bibliothèques suffisamment importants pour imposer une comparaison réelle des séries, traces et exporteurs.

Actuator peut exposer Prometheus via /actuator/prometheus, lorsque l’endpoint est disponible et exposé. Le fait que ce chemin retourne 200 ne garantit ni les noms de séries, ni les tags, ni la cardinalité, ni les conventions dont dépend votre backend.

Contrôle de parité

Ce qu’il faut comparer

Metrics

noms, unités, tags, type counter/gauge/timer

Cardinalité

nombre de séries par métrique

Traces

W3C/B3 selon contrat, parentage, sampling

Logs

timestamp, severity, trace/span IDs, JSON fields

Health

indicators, groups, readiness/liveness

Management

port, bind address, TLS, security

Exporters

endpoint, auth, queue, retry, drops

Agents

instrumentation, versions, overhead

Alertes

requêtes et seuils sur données du canary

Reprenons pricing-api. Le second module interne, platform-observability-autoconfigure, contenait un MeterBinder qui publiait pricing.reprice.completed. Pendant le même nettoyage de starters, il disparaît du graphe de dépendances. Là encore, l’application compile et les tests métier restent verts. /actuator/health fonctionne ; même /actuator/prometheus peut fonctionner pour d’autres métriques. Mais la série critique du dashboard a disparu.

Le test de parité doit exécuter une vraie opération puis contrôler la télémétrie :

POST /api/admin/reprice/42   -> 202
scrape /actuator/prometheus
assert pricing_reprice_completed_total{outcome="accepted"} increased by 1

Ce test échoue sur le candidat Boot 4 fautif. Le signal est encore plus fort en canary : le volume métier reprice accepted augmente dans les logs ou la base, alors que la métrique reste nulle. Cette contradiction est une alerte de telemetry parity, pas une alerte business.

Vérifiez aussi les dashboards et alertes en exécutant leurs requêtes réelles contre les données canary. Une métrique renommée « proprement » mais non traduite dans les alertes équivaut opérationnellement à une métrique perdue.

Les notes Boot 4.1 ajoutent par ailleurs des évolutions autour des conventions d’observation Kafka/RabbitMQ et des options OpenTelemetry ; ce sont des raisons supplémentaires de comparer ce qui arrive dans votre backend plutôt que de déduire la compatibilité depuis la configuration Spring.

Gate : aucune métrique de SLO (service-level objective, objectif de niveau de service), alerte de sécurité ou signal de saturation ne peut disparaître, changer de cardinalité de façon non approuvée ou perdre sa corrélation sans décision explicite.

Test Data, Messaging, Web, Scheduling, and External Integrations

Le changement de BOM fait traverser plusieurs générations à la fois : Hibernate ORM passe ici de 6.6.53.Final à 7.4.5.Final, Hibernate Validator à la génération 9, Flyway de 11.7.2 à 12.4.0, Spring Kafka de 3.3.16 à 4.1.1 et Testcontainers de 1.21.4 à 2.0.5. Ces versions sont gérées par Boot, mais leurs contrats applicatifs doivent être testés par le service.

Boundary

Test obligatoire

JPA/Hibernate

mapping, lazy/eager, pagination, locks, SQL critique

Flyway

migration depuis copie réaliste + rollback applicatif

Transactions

rollback, propagation, retry, deadlock

Cache

sérialisation, TTL, invalidation

Kafka/broker

producer/consumer, headers, schema, DLQ, retries

JSON

snapshots Jackson 2/3 et contrats externes

HTTP clients

timeout, proxy, TLS, erreurs 4xx/5xx

Validation

payloads limites et messages d’erreur

Scheduler

timezone, concurrence, locks, rattrapage

Cloud SDK

auth, retries, pagination, endpoints

Les tests de contrat doivent inclure producteurs et consommateurs indépendants. Pour Kafka, produisez avec la version candidate et consommez avec le service encore en production ; faites aussi l’inverse. Une mise à niveau qui exige le déploiement simultané de tous les consommateurs détruit une partie de votre capacité de rollback.

Pour la base, démarrez une copie ou un environnement représentatif avec le schéma actuel, appliquez Flyway 12 via le candidat, exécutez les transactions métier, puis vérifiez si l’ancienne application 3.5.16 peut encore fonctionner sur ce schéma. C’est la preuve dont le runbook de rollback a besoin.

Jackson 3 mérite des golden files (jeux JSON de référence) pour API entrante, API sortante, événements et colonnes JSON. Les changements de sérialisation sont particulièrement dangereux lorsqu’un test Java compare seulement des objets désérialisés et ne compare jamais les octets envoyés.

Gate : chaque intégration majeure possède au moins un test contre une vraie implémentation ou une simulation contractuelle fidèle. Les mocks sont utiles aux tests unitaires ; ils ne certifient ni le driver, ni le protocole, ni le broker.

Rebuild Containers and Qualify Native Images Separately

Le JAR qui passe ses tests n’est pas encore l’image qui sera exploitée. Recréez l’image OCI (Open Container Initiative) avec le JDK/runtime cible, puis comparez utilisateur non-root, filesystem, certificats, DNS, timezone, ENTRYPOINT, healthchecks, signaux Unix, mémoire, CPU et comportement d’arrêt gracieux.

La supply chain doit conserver au minimum le digest de l’image, l’origine des couches, le SBOM (Software Bill of Materials, inventaire des composants logiciels) et la provenance du build selon les contrôles de votre organisation. Une version de base mutable invalide une partie de l’explication d’un incident : deux images portant le même tag peuvent ne plus représenter le même système.

Chemin de qualification

Artefact

Gate indépendant

JVM locale/CI

JAR

tests fonctionnels

JVM en OCI

image

runtime/container

AOT JVM

image/JAR AOT

bean graph et hints

GraalVM native

binaire/image native

compatibilité closed-world

Le dernier point est volontairement séparé. Les GraalVM native-image requirements de Spring Boot expliquent que l’analyse native fonctionne selon un modèle « closed world » : réflexion, ressources, sérialisation et proxies dynamiques peuvent nécessiter des runtime hints. La configuration de beans dépendant de profils ou propriétés doit également être pensée dans le contexte de l’AOT (Ahead-of-Time compilation, traitement anticipé à la construction).

Treat GraalVM Reachability and Reflection as a Separate Gate

Boot 4.1.1 exige pour ses native images GraalVM 25 ou ultérieur et Native Build Tools 1.1.8 selon ses system requirements.

Le test native doit couvrir précisément les chemins rarement atteints par l’analyse statique : sérialiseurs custom, réflexion, ressources classpath, proxies, drivers, validation, templates, clients générés et chargement de certificats. Mesurez ensuite démarrage, mémoire résidente, débit, latence et comportement lors d’un crash.

Un succès JVM ne certifie pas le native. Un succès AOT JVM ne certifie pas non plus exactement le binaire GraalVM. Chacun doit avoir son propre artefact, ses résultats et son statut de promotion.

Pour un Spring Boot native image upgrade, j’interdis également de justifier la migration principale par un benchmark native avant d’avoir démontré l’équivalence fonctionnelle. Optimiser un artefact qui ne respecte pas la même politique de sécurité ou les mêmes contrats ne produit pas un gain exploitable.

Rollback : conservez séparément l’image JVM connue bonne et, si le native est en production, son propre binaire connu bon. Ne rendez jamais le rollback Boot dépendant du succès de la qualification GraalVM.

Deploy Canaries and Compare Business Behavior

La préproduction répond à « peut-il fonctionner ? ». Le canary répond à « se comporte-t-il comme notre production sous ses vraies distributions de trafic, données et dépendances ? ».

Je commence avec une population isolable : instances dédiées, header/routage déterministe ou faible pourcentage de trafic. Les pourcentages et durées ci-dessous sont une politique recommandée, pas un défaut Spring : adaptez-les à votre volume et à votre capacité à détecter une anomalie.

Vague

Exemple de trafic

Durée minimale indicative

Condition de promotion

Shadow/synthétique

0 % écriture réelle

plusieurs cycles

parité des réponses observables

Canary initial

1–2 %

1–2 h

aucune alerte nouvelle

Canary élargi

5–10 %

6 h+

sécurité/télémétrie stables

Vague intermédiaire

25 %

cycle business complet

SLO et dépendances stables

Majoritaire

50 %

période de pointe

pas de dérive

Généralisation

100 %

après décision

rollback toujours disponible

Comparez au minimum taux de succès métier, 4xx/5xx, latence, CPU, mémoire, GC (garbage collection), saturation des pools, connexions DB, lag Kafka, décisions 401/403, métriques exportées, spans rejetés et erreurs de l’agent. Ne vous contentez pas d’un seuil absolu : comparez le candidat au groupe contrôle exposé au même trafic.

Ajoutez des parcours synthétiques qui testent précisément le cas du service témoin : utilisateur sans pricing:write → 403, utilisateur autorisé → succès, compteur pricing.reprice.completed → incrément, trace → visible, log → corrélé. C’est ce qui aurait détecté à la fois la règle de sécurité perdue et la métrique manquante.

L’article sur les API engineering trends and best practices fournit un contexte plus large sur l’exploitation d’API ; le Spring Boot canary deployment ici est une procédure de migration, avec stop conditions explicites.

Stop conditions recommandées : anomalie d’autorisation, disparition d’un signal critique, erreur de schéma, hausse inexpliquée de 5xx, saturation nouvelle ou écart business non compris. En présence d’une condition rouge, on arrête la progression avant de débattre du pourcentage suivant.

Rehearse Rollback and Dependency Forward-Fixes

Le rollback n’est pas « l’ancien tag Docker existe ». C’est la capacité démontrée de redonner le trafic à l’ancienne version sans violer les données, les messages ou les contrats créés depuis le déploiement.

Le Spring Boot rollback plan doit commencer avant la première migration de schéma. Les changements de base doivent rester compatibles avec l’ancienne application pendant toute la fenêtre où un retour est requis. Privilégiez une séquence expand/contract : ajouter structures ou colonnes, déployer les applications compatibles, migrer les usages, puis supprimer l’ancien contrat seulement lorsque le rollback binaire n’est plus une exigence.

Événement

Action

Précondition

Régression HTTP

rerouter vers 3.5.16

API/schema compatibles

Security regression

stop canary + rollback

ancien artefact prêt

Metrics seulement

rollback ou forward-fix

capacité d’observer le correctif

Migration DB incompatible

forward-fix possible

rollback binaire peut être bloqué

Événement Kafka nouveau

ancien consumer doit tolérer

schéma compatible

CVE dépendance

patch ciblé/forward-fix

impact réévalué

Le cas « forward-fix » compte autant que le retour arrière. Si le candidat a déjà écrit une structure de données que 3.5.16 ne sait pas lire, un rollback aveugle peut produire un incident plus grave. Le dossier de changement doit donc préciser le dernier point où le rollback binaire est sûr et ce qui arrive ensuite.

Répétez la manœuvre : réduire Boot 4 à zéro instance, ramener 3.5.16, vérifier health, sécurité, métriques et transactions. Puis redéployer le candidat. Mesurez l’objectif de restauration fixé par votre organisation et documentez les commandes/routages exacts.

Conservez l’artefact, son digest, sa configuration, son SBOM et les versions de dépendances associées. « Rebuilder l’ancien commit » n’est pas équivalent à restaurer l’ancien artefact : les dépôts de dépendances et images de base peuvent avoir évolué.

Gate : aucun passage à 100 % sans répétition réussie du chemin de retour ou décision explicite indiquant que la fenêtre de rollback est fermée pour une raison data-side documentée.

Execute the 60-Day Spring Boot 4.1 Migration Plan

Soixante jours imposent de paralléliser l’inventaire et la préparation tout en maintenant des gates séquentiels. Cela ne signifie pas soixante jours de développement à temps plein : c’est une fenêtre de gouvernance qui donne aux équipes sécurité, observabilité, data et plateforme le temps de produire leurs preuves.

Jours

Travail

Owner principal

Sortie obligatoire

1–7

inventaire et frontière

release engineer

graphe + versions + rollback

8–14

baseline

équipes service/SRE

golden tests + télémétrie

15–21

Java/build

plateforme/CI

Java 21 + Maven qualifiés

22–35

Boot 4 / Framework 7

service

compile + contexte + modules

36–45

intégrations/parité

service + data + security

tests réels verts

46–54

canaries

SRE/release

rapports de vagues

55–60

exceptions et clôture

owner migration

100 % ou décision de report

Jours 1–7 : capturez dependency tree, BOM, overrides, starters, auto-configurations, conteneur, agents, image et plateforme. Lisez les release notes 3.5, 4.0 et 4.1 et assignez chaque changement pertinent.

Jours 8–14 : gelez les contrats fonctionnels, politique security et signaux observability. Produisez le test qui prouve que pricing:read n’autorise jamais le repricing et celui qui prouve l’existence de la métrique critique.

Jours 15–21 : qualifiez Java/build indépendamment. Les sujets généraux couverts par top backend skills sont adjacents ; ici l’objectif est un environnement de build reproductible.

Jours 22–35 : effectuez la Spring Framework 7 migration et la Spring Boot modularization. Traitez Jackson, starters, auto-configurations, test modules et propriétés.

Jours 36–45 : exécutez PostgreSQL/Flyway/Hibernate, Kafka, cache, clients HTTP, security et observability en conditions réalistes. Aucune dérogation critique ne reste verbale.

Jours 46–54 : canary progressif avec groupe contrôle. Toute régression d’autorisation, data ou signal critique stoppe la vague.

Jours 55–60 : fermez les bridges temporaires, supprimez properties-migrator, classez les exceptions et répétez rollback. Si un risque ne peut pas être clos, la bonne décision peut être de différer la généralisation plutôt que de transformer une date interne en obligation de production.

Le rôle du release owner est de garder la matrice honnête : « vert » signifie preuve jointe ; « accepté » signifie risque nommé, propriétaire nommé et stratégie de sortie. Il ne signifie jamais « aucun incident observé jusqu’ici ».

Une migration Spring Boot 4.1 sûre se résume finalement aux cinq surfaces de preuve : le build et ses dépendances, le comportement applicatif, la politique de sécurité, la télémétrie, puis le packaging et le runtime. Un service qui compile mais échoue sur une seule de ces surfaces n’est pas encore équivalent.

Les trois premières actions sont concrètes. Premièrement, épinglez votre patch 3.x actuel et rejoignez la dernière 3.5.x supportée avant de franchir Boot 4. Deuxièmement, exportez le graphe de dépendances et construisez une baseline testable de security et observability. Troisièmement, séparez le changement Java/build du changement Spring afin de conserver un diagnostic et un rollback compréhensibles. La compétence utile n’est pas de mémoriser chaque version : c’est de savoir produire les preuves qui permettent à une équipe de décider si un changement peut recevoir du trafic.

Pour élargir ces fondations au-delà d’un seul upgrade, les contenus sur les tools employers actually request donnent un contexte général, tandis que le Refonte Learning Software Engineering Program annonce un parcours de trois mois, 12–14 heures par semaine, couvrant notamment full-stack, cloud et microservices, systèmes temps réel, performance, application security, systèmes scalables, cycle de développement et projets pratiques. La page présente également le bachelor en informatique, ingénierie, mathématiques ou domaine apparenté dans ses informations d’admission, et cite Software Engineer, Full-Stack Developer et Cloud Engineer parmi les orientations. La page du programme ne confirme pas la couverture spécifique de Java, Spring Boot, Spring Framework, Maven, Gradle, Actuator ou GraalVM.