Spring Boot 4.0: o que quebra na auto-configuração e no Jackson antes de migrar sua API
As release notes oficiais, atualizadas em setembro de 2026, confirmam Jackson 3.0 como padrão e renomeiam beans e propriedades usados por quem configura observabilidade e persistência. Nada disso aparece como erro óbvio: aparece como JSON ou métrica que silenciosamente parou de bater.

O que entra no major bump
Spring Boot 4.0 não é só um número redondo. As release notes oficiais do projeto, revisadas em setembro de 2026, listam uma lista longa de upgrades de dependência: Spring Framework 7.0, Jakarta Servlet 6.1, Hibernate 7.2, Tomcat 11.0, Jetty 12.1 e, o que mais interessa para quem serializa JSON todo dia, Jackson 3.0. A recomendação do próprio time é dolorosamente simples: atualize primeiro para a 3.5, estabilize, e só depois suba para a 4.0.
Essa recomendação não é burocracia. Major bump de Jackson é o tipo de mudança que não aparece em log de erro: aparece em campo que some do JSON, data que serializa diferente, ou teste de contrato que passa a falhar sem ninguém ter tocado no código de domínio. É aí que a auto-configuração do Spring Boot entra: ela decide qual ObjectMapper seu projeto usa, e ela mudou.
Jackson 3: o suporte ao 2 já nasce com prazo de validade
A informação central das release notes está discreta, no fim da página, na seção de depreciações: o suporte ao Jackson 2 continua existindo na 4.0, mas já embarca em formato depreciado. Ou seja, funciona, mas não é para onde o projeto está indo. Quem tem bibliotecas de terceiros que dependem diretamente de com.fasterxml.jackson.databind na versão 2.x precisa checar compatibilidade antes de travar a versão do Boot.
Na prática, isso significa três frentes de atenção, na minha leitura:
- Dependências transitivas: se algum starter ou lib interna do seu projeto força uma versão 2.x do Jackson via
dependencyManagement, ela agora está competindo com o Jackson 3 que o Boot traz por padrão. - Módulos customizados:
Module,SerializereDeserializerescritos contra a API do Jackson 2 não sobem de graça para a 3 só porque o jar está no classpath. - Configuração via
Jackson2ObjectMapperBuilder: nomes de classe que carregam "2" no pacote tendem a ser os primeiros candidatos a depreciação formal nas próximas minors.
A release notes não detalha quais defaults de serialização mudam de comportamento entre o Jackson 2 e o 3 — e isso, para mim, é o argumento mais forte a favor de testes de contrato automatizados em vez de inspeção visual do JSON de resposta. Diferença de formatação de data ou de ordenação de campo é exatamente o tipo de regressão que passa despercebida numa revisão manual de Pull Request.
Quando o @ConditionalOn* muda de nome embaixo do capô
A parte que mais se conecta com o ângulo de auto-configuração quebrada está espalhada na seção "Miscellaneous" das release notes, e é fácil de pular na leitura corrida. Várias anotações condicionais, propriedades e classes de auto-configuração foram renomeadas para consistência — o tipo de mudança que o compilador acusa na hora, mas que application.yml engole em silêncio.
| Antes (3.x) | Depois (4.0) | Onde costuma doer |
|---|---|---|
@ConditionalOnEnabledTracing | @ConditionalOnEnabledTracingExport | Auto-configuração customizada que estende a do Boot |
management.tracing.enabled | management.tracing.export.enabled | Propriedade ignorada sem erro, tracing some sem aviso |
spring.dao.exceptiontranslation.enabled | spring.persistence.exceptiontranslation.enabled | Idem: propriedade órfã no YAML |
ScheduledTasksObservabilityAutoConfiguration | ScheduledTasksObservationAutoConfiguration | Quebra em build para quem importa a classe diretamente |
Tem ainda um ponto estrutural, não cosmético: membros públicos (fora constantes) foram removidos das classes de auto-configuração. O projeto sempre deixou claro que essas classes não são API pública, mas na prática muita gente estendia ou reaproveitava métodos delas. Isso quebra em tempo de compilação, o que é bom — é o tipo de erro que você prefere ver no CI, não em produção.
Testando o contrato antes de trocar a versão
O recurso mais útil que a 4.0 traz para quem vai migrar não é de serialização, é de teste: o RestTestClient. Segundo a documentação, ele pode ser injetado tanto num @SpringBootTest com @AutoConfigureMockMvc (operando sobre o MockMvc subjacente) quanto num teste de integração real, com porta definida ou aleatória, apontando para o servidor de verdade.
Num projeto típico, o esqueleto de teste de contrato que eu escreveria antes de trocar a versão do Boot é algo assim:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class PedidoApiContractTests {
@Autowired
RestTestClient restTestClient;
@Test
void retornaPedidoNoFormatoEsperado() {
restTestClient.get().uri("/api/pedidos/42")
.exchange()
.expectStatus().isOk()
.expectBody()
.jsonPath("$.id").isEqualTo(42)
.jsonPath("$.status").isEqualTo("CONFIRMADO")
.jsonPath("$.criadoEm").exists();
}
}O valor aqui não é o RestTestClient em si, é o momento: rodar essa suíte contra o build na 3.5 (baseline) e depois contra a 4.0, comparando campo a campo. Divergência de tipo, nome de campo ou formato de data aponta exatamente para onde investigar — Jackson, @ConditionalOn* renomeado, ou mudança de comportamento de outro componente.
O checklist que eu rodaria numa migração real
Seguindo a própria recomendação do projeto, a ordem que faz sentido é:
- Subir para Spring Boot 3.5 primeiro, se ainda não estiver lá, e garantir build e testes verdes nessa versão como baseline.
- Trocar a versão do Boot para 4.0 (milestones já saem direto no Maven Central desde a M1, sem precisar do repositório
repo.spring.io). - Recompilar e tratar primeiro os erros de build: uso direto de classes de auto-configuração que perderam membros públicos,
@ConditionalOnEnabledTracinge referência direta aScheduledTasksObservabilityAutoConfiguration. - Rodar
grepnoapplication.yml/application.propertiesatrás demanagement.tracing.enabledespring.dao.exceptiontranslation.enabled, renomeando para as novas chaves. - Checar se alguma dependência força Jackson 2.x diretamente no
pom.xmloubuild.gradle, já que o suporte segue existindo, mas depreciado. - Rodar a suíte de testes de contrato com
RestTestClientcontra as duas versões e comparar o JSON campo a campo, não só o status HTTP.
Quando não vale migrar ainda
Nem todo projeto deveria subir para a 4.0 neste momento, e isso também é parte honesta do checklist. Se a API tem pouca ou nenhuma cobertura de teste de contrato, migrar agora é apostar que nada no JSON mudou — e a própria release notes já avisa que houve renomeação de propriedades e classes em múltiplas frentes. Se o projeto depende pesadamente de bibliotecas de terceiros ainda presas ao Jackson 2.x sem previsão de atualização, o caminho mais seguro é esperar a lib migrar primeiro, não forçar a convivência.
O Gradle 9 já é suportado, mas o Gradle 8.14+ continua funcionando — não é obrigatório trocar as duas coisas no mesmo commit. Separar a atualização de build tooling da atualização de framework reduz a superfície de erro quando algo quebra: você sabe, pelo menos, que não foi o Gradle.
Fonte: Spring Boot 4.0 — Release Notes (wiki oficial do projeto)
Este artigo foi escrito por Bisneto Braga, colunista de back-end. Conteúdo produzido por agente de IA da redação iMasters, sob revisão editorial humana. Saiba como produzimos no expediente.
JDK 25 traz a quinta prévia do Structured Concurrency, não a versão estável
Entenda o que muda na quinta prévia da API StructuredTaskScope e por que ainda não é hora de usar `--enable-preview` em produção.













