Molti sistemi enterprise girano ancora su Spring Boot 2.7 o 3.x. I team sanno che l'aggiornamento è necessario, ma perde sempre contro le funzionalità richieste dal business. Ora decide il calendario: il supporto open source di Spring Boot 3.5 è terminato il 30 giugno 2026 e quello della 4.0 termina il 31 dicembre 2026. In questo articolo descriviamo come aggiorniamo applicazioni Spring di grandi dimensioni senza fermare lo sviluppo. Versioni e date sono aggiornate a ottobre 2026 e provengono da spring.io e dalle guide di migrazione ufficiali.

A che punto sono le date di supporto

Dal calendario di supporto di Spring Boot:

Linea Supporto open source fino al Supporto commerciale fino al
2.7.x 30 giugno 2023 (terminato) 30 giugno 2029
3.4.x 31 dicembre 2025 (terminato) 31 dicembre 2026
3.5.x 30 giugno 2026 (terminato) 30 giugno 2032
4.0.x 31 dicembre 2026 31 dicembre 2027
4.1.x 31 luglio 2027 31 luglio 2028

La support policy di Spring garantisce a ogni minor release almeno 13 mesi di supporto e all'ultima minor di ogni linea principale (2.7, 3.5) altri cinque anni di supporto enterprise. Il supporto commerciale fa guadagnare tempo, ma non elimina il lavoro, e le librerie attorno a Spring continuano comunque a evolversi. Come destinazione vi consigliamo Spring Boot 4.1 (4.1.1 nel momento in cui scriviamo): la 4.0 esce dal supporto open source fra meno di tre mesi.

Il percorso incrementale

Le guide ufficiali sono chiare: prima di passare alla 3.0 si aggiorna all'ultima 2.7.x, prima della 4.0 all'ultima 3.5.x. Ciò che è deprecato in una linea viene rimosso nella major successiva, quindi eliminare i warning di deprecazione fa parte dell'upgrade, non è pulizia da rimandare.

  1. Su 2.7, prima Java. Spring Boot 2.7.18 richiede Java 8 ed è compatibile fino a Java 21. Passare a Java 17 o 21 restando sulla versione attuale di Boot separa i problemi della JVM da quelli del framework. Portate anche Spring Security alla 5.8, come raccomanda la guida della 3.0.
  2. Da 2.7 a 3.5. La vera rottura avviene con la 3.0: Java 17 come minimo, Jakarta EE 10, Hibernate 6, Spring Security 6. Da lì si risale alle minor successive fino alla 3.5, leggendo ogni release note. Spring Boot 3.5.16 è compatibile con Java da 17 a 25.
  3. Da 3.5 a 4.1. Spring Framework 7, Jakarta EE 11 con Servlet 6.1, Hibernate 7, Jackson 3, starter modulari. Spring Boot 4.1.1 richiede Java 17 ed è compatibile fino a Java 26. Di solito puntiamo a Java 21 o a Java 25, quest'ultimo disponibile in GA dal 16 settembre 2025.

A ogni passo aggiungete temporaneamente spring-boot-properties-migrator: all'avvio segnala le proprietà rinominate o rimosse e le rimappa a runtime. Va tolto quando i warning sono spariti.

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-properties-migrator</artifactId>
  <scope>runtime</scope>
</dependency>

Jakarta EE e gli altri breaking change

Con Boot 3 i package passano da javax.* a jakarta.*. Gli import sono la parte facile; quella difficile sono le librerie che pubblicano solo artefatti javax, spesso transitive: cercate nell'albero delle dipendenze javax.servlet, javax.persistence e javax.validation e trattate ogni occorrenza come una libreria da aggiornare, sostituire o isolare. Attenzione anche ai cambiamenti che compilano ma si comportano diversamente, come il trailing-slash matching, disattivato di default dalla 3.0: GET /orders/ non corrisponde più a /orders.

Boot 4 porta la sua lista. I punti che di solito richiedono più tempo:

  • Jackson 3: i package passano da com.fasterxml.jackson a tools.jackson (le annotazioni mantengono il nome) e i customizer cambiano nome. Jackson 2 resta disponibile come ponte con il modulo deprecato spring-boot-jackson2.
  • Starter modulari: spring-boot-starter-web diventa spring-boot-starter-webmvc, Flyway e Liquibase richiedono starter dedicati. spring-boot-starter-classic è una soluzione transitoria.
  • Funzionalità rimosse: Undertow è stato eliminato, perché non è ancora compatibile con Servlet 6.1.
  • Test: @MockBean e @SpyBean sono sostituiti da @MockitoBean e @MockitoSpyBean, e @SpringBootTest non configura più MockMvc senza @AutoConfigureMockMvc.

Hibernate 6 e 7: cosa verificare

I cambiamenti di Hibernate raramente rompono la build: cambiano l'SQL generato e il rapporto con lo schema. Spring Boot 3.0 è passato a Hibernate 6.1, Boot 4.0 a Hibernate 7.2 con Jakarta Persistence 3.2, e Boot 4.1 include Hibernate 7.4. Dalle guide di migrazione ufficiali, meritano attenzione:

  • Sequence (6.0): i generatori impliciti usano una sequence per entità (<entity>_seq) invece di hibernate_sequence, con allocation size 50. Gli schemi esistenti richiedono nuove sequence, oppure un'impostazione di compatibilità mentre pianificate la modifica:

    spring.jpa.properties.hibernate.id.db_structure_naming_strategy=legacy
    
  • Tipi: Instant, gli UUID su MariaDB e SQL Server e la memorizzazione dei fusi orari sono mappati diversamente. Eseguite la validazione dello schema su una copia della produzione.

  • Fetching (6.0): la natura lazy delle associazioni mappate con FetchMode.JOIN è ora rispettata anche quando si carica un'entità per id. Aspettatevi eccezioni di lazy loading o query aggiuntive.

  • API rimosse (7.0): Session#save, update, saveOrUpdate, delete e load lasciano il posto a persist, merge, remove e getReference.

  • Validazione più severa (7.0): le annotazioni di mapping in posizione errata, prima ignorate, ora generano errori.

Per i casi d'uso critici confrontiamo l'SQL generato prima e dopo e contiamo le query nei test, per far emergere le regressioni N+1 prima della produzione.

OpenRewrite: un acceleratore, non una garanzia

OpenRewrite automatizza le modifiche meccaniche: import, tipi rinominati, proprietà, versioni delle dipendenze. Le ricette rilevanti includono UpgradeSpringBoot_3_5 e UpgradeSpringBoot_4_0 in rewrite-spring, JavaxMigrationToJakarta e UpgradeToJava25 in rewrite-migrate-java. Partite da un dry run e revisionate la patch come qualsiasi altra modifica:

mvn -U org.openrewrite.maven:rewrite-maven-plugin:dryRun \
  -Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-spring:RELEASE \
  -Drewrite.activeRecipes=org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_5

Tre avvertenze. Leggete cosa contiene una ricetta: quella community per Spring Boot 4.0 copre Spring Framework 7, Spring Security 7, Hibernate 7.1, Testcontainers 2 e i nuovi nomi degli starter, ma non una migrazione completa del vostro codice a Jackson 3. Le ricette cambiano la sintassi, non la semantica: non si accorgono che una query ora restituisce righe diverse. Infine verificate la licenza: il framework e i plugin di build sono Apache 2.0, ma molte ricette Spring e di migrazione sono sotto Moderne Source Available License, che limita alcuni usi commerciali, e gli artefatti delle ricette si stanno spostando da Maven Central a un repository che richiede autenticazione.

I test come rete di sicurezza

Prima di cambiare qualsiasi versione, fissate il comportamento attuale con test di caratterizzazione: test che registrano ciò che il sistema fa oggi, non ciò che dovrebbe fare. I più utili stanno ai confini: risposte REST (inclusa la serializzazione JSON, che Jackson 3 può cambiare), messaggi pubblicati e righe scritte dalle transazioni critiche.

Eseguiteli su infrastruttura reale con Testcontainers, non su database in memoria che nascondono le differenze di dialetto e di tipo. Su Boot 2.7 le proprietà del container si collegano con @DynamicPropertySource; da Boot 3.1 lo fa @ServiceConnection:

@Testcontainers
@SpringBootTest
@AutoConfigureMockMvc
class OrderApiCharacterizationTest {

    @Container
    @ServiceConnection
    static PostgreSQLContainer postgres = new PostgreSQLContainer("postgres:16");

    // registrare le risposte di oggi, verificare che restino invariate a ogni passo
}

Boot 4.0 passa a Testcontainers 2.0, i cui moduli hanno nuovi nomi di artefatto (per esempio testcontainers-postgresql): anche il codice di test va migrato. Cambiate l'infrastruttura del test, non le asserzioni. Per le API usate da altri team, i test di contratto proteggono ciò che esponete.

Igiene delle dipendenze e CVE

L'upgrade è anche il momento per riprendere il controllo delle dipendenze:

  • Lasciate al BOM di Spring Boot la gestione delle versioni; ogni override manuale deve avere una motivazione scritta.
  • Prima di ogni passo verificate la compatibilità delle dipendenze non gestite da Boot, come Spring Cloud.
  • Individuate presto le librerie abbandonate: sono la causa più frequente di un upgrade che si blocca.
  • Generate un SBOM (CycloneDX) nella build e analizzatelo in CI. Da Spring Boot 3.3 Actuator può esporlo con un endpoint dedicato.
  • Dopo il rilascio continuate ad applicare le patch release: è lì che arrivano le correzioni di sicurezza.

Rilascio: piccoli passi reversibili

Ogni passo va in produzione da solo, con un piano di rollback concordato in anticipo:

  • Un cambiamento per rilascio: l'upgrade di Java, una minor di Boot e una modifica di comportamento di Hibernate non escono insieme.
  • Modifiche al database in modalità expand/contract: prima si aggiungono nuove sequence o colonne, le vecchie si rimuovono solo quando la nuova versione è stabile, così la release precedente può ancora girare.
  • Rilascio canary o blue/green, confrontando tassi di errore, latenza e numero di query tra istanze vecchie e nuove. Boot 4 attiva di default le probe di liveness e readiness, utili su Kubernetes.
  • Feature flag per i comportamenti che cambiate intenzionalmente durante l'upgrade, per esempio una query riscritta.

Checklist

  • Linea di destinazione scelta e date di supporto documentate
  • Java aggiornato separatamente, sulla versione attuale di Boot
  • Deprecazioni eliminate; properties migrator aggiunto e poi rimosso
  • Dipendenze javax censite e alternative Jakarta individuate
  • Sequence, tipi e fetching di Hibernate verificati su un database simile alla produzione
  • Test di caratterizzazione e di integrazione verdi prima e dopo ogni passo
  • Modifiche di OpenRewrite revisionate, termini di licenza verificati
  • Rilascio con canary e rollback provato

Riferimenti ufficiali: guida di migrazione a Spring Boot 3.0, guida di migrazione a Spring Boot 4.0, guide di migrazione di Hibernate 6.0 e 7.0.

Se vi serve aiuto per pianificare o eseguire l'upgrade, trovate il nostro servizio di modernizzazione e lo Sprint di modernizzazione Spring, oppure contattateci.

Tutti gli articoli

Raccontateci il vostro sistema.

Descrivete la sfida in poche righe: una piattaforma da modernizzare, un incidente che si ripete, una vulnerabilità da chiudere, un'idea di AI. Rispondiamo personalmente, di solito entro due giorni lavorativi.