DevFix
Spring Boot已验证

Spring Boot 2 升 3 升级踩坑:javax 变 jakarta,一次平台级迁移

@debug_master更新于 3 天前阅读 6 min0

一句话先说结论:Spring Boot 3 是基于 Spring Framework 6 的平台级升级,最低要求 Java 17,并把整个生态从 javax.* 迁移到 jakarta.*。升级后最先崩的往往是满屏的包找不到——javax.persistencejavax.servlet 这些全都要改成 jakarta.*。再叠上 Spring Security 6 移除了 WebSecurityConfigurerAdapter、Hibernate 升到 6,升级是一项“重命名 + 重写”的工程。

背景

Spring Boot 3.x 于 2022 年末发布,踩在三大变化之上:

  1. JDK 强制升到 17+,Java 8 / 11 不再支持。
  2. Jakarta EE 9+ 命名空间迁移javax.* 全部改为 jakarta.*
  3. 生态大版本同步升级:Spring Framework 6、Spring Security 6、Hibernate 6、Tomcat 10。

所以它不是“小版本点一下”,而是把好几条兼容性边界同时跨过去。

现象

升级之后最常见的两类报错:

一是 Java 版本不够:

UnsupportedClassVersionError: com/example/Application (class file version 61.0)

class file version 61.0 对应的就是 Java 17。)

二是满屏的包找不到:

import javax.persistence.Entity;      // error: package javax.persistence does not exist
import javax.servlet.http.HttpServletRequest;  // error
import javax.validation.constraints.NotNull;   // error

Hibernate/JPA 实体的 @Entity@Column 等注解直接失效。

根因分析

这个 javaxjakarta 的变化,源头不在 Spring,而在整个 Java 企业生态。

2017 年 Oracle 把 Java EE 交给 Eclipse 基金会,规范、参考实现、TCK 都捐了,但 javax 这个命名空间商标 Oracle 没放。Eclipse 基金会不能修改 javax.* 包并以 Java EE 名义发布,于是整体改名:Java EE 变成 Jakarta EE,企业级包名从 javax.* 换成 jakarta.*。Jakarta EE 9 是第一次纯改名发布,不做新特性,就只是换包名。Spring Boot 3 / Spring Framework 6 跟随采用了这套新命名空间。

这里有个最容易误伤的点:不是所有 javax 都要改。只有原来属于 Java EE 的包才变了,JDK 核心自带的 javax 没动:

要改(原 Java EE) 不改(JDK 自带)
javax.persistencejakarta.persistence javax.sql
javax.servletjakarta.servlet javax.crypto
javax.validationjakarta.validation javax.net.ssl
javax.annotationjakarta.annotation javax.swing
javax.inject / javax.transactionjakarta.* javax.naming

所以批量替换时得用白名单,不能无脑把所有 javax 都换掉。

解决方案

1. 先升 JDK 到 17

pom.xml

<properties>
    <java.version>17</java.version>
</properties>

Gradle:

java {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
}

2. 批量替换 Jakarta 包名

只改 Jakarta EE 相关的那几个前缀,用 IDE 的 Find in Files → Replace in Files 一键替换:

javax.servlet    → jakarta.servlet
javax.persistence → jakarta.persistence
javax.validation → jakarta.validation
javax.annotation → jakarta.annotation
javax.transaction → jakarta.transaction

替换后:

// Before (Boot 2.x)
import javax.persistence.Entity;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;

// After (Boot 3.x)
import jakarta.persistence.Entity;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.NotNull;

依赖坐标也跟着换,例如:

// Boot 2.x
implementation 'javax.validation:validation-api'
// Boot 3.x
implementation 'jakarta.validation:jakarta.validation-api'

3. 重写 Spring Security 配置

Spring Security 6 彻底移除了 WebSecurityConfigurerAdapter,改成 SecurityFilterChain Bean + Lambda DSL:

// ❌ Boot 2.x(已删除)
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/public/**").permitAll()
            .anyRequest().authenticated();
    }
}

// ✅ Boot 3.x
@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(auth -> auth
                .requestMatchers("/public/**").permitAll()
                .anyRequest().authenticated()
            );
        return http.build();
    }
}

方法是 antMatchersrequestMatchersauthorizeRequestsauthorizeHttpRequests,链式 .and() 改成 Lambda。

4. 检查第三方依赖和配置项

  • Swagger/SpringFox 不支持 Jakarta,换成 springdoc-openapi-starter-webmvc-ui
  • 老版 Hibernate(5.x)不支持 Jakarta,必须升到 Hibernate 6。
  • 配置键有一批被重命名/删除,典型如 spring.redis.*spring.data.redis.*。可以临时引入 spring-boot-properties-migrator,它会在启动时打印哪些旧配置键该改。
  • Hibernate 6 的 HQL / dialect 有差异,session.createQuery("from User") 最好改成带上返回类型 createQuery("from User", User.class)

5. 用工具省力

大项目手动替换容易漏。可以用 OpenRewrite 的迁移 recipe 自动重写 javax.* imports 和依赖版本;spring-boot-properties-migrator 负责提示配置项迁移。

小结

  • 这次升级的关键词是“重命名 + 重写”:javaxjakartaWebSecurityConfigurerAdapterSecurityFilterChain、Hibernate 5 → 6。
  • javax 替换一定要分清楚哪些是 Jakarta EE、哪些是 JDK 自带,别误伤 javax.sql 这类。
  • 顺序建议:先升 JDK 17 → 再做包名替换 → 重写 Security → 逐个校验第三方库的 Jakarta 兼容版本。
  • 升级后跑一遍 spring-boot-properties-migrator,比手工翻 migration guide 更不容易漏。

来源

最后更新于 2026-08-22

这篇帮到你了吗?

刚解决了一个棘手的报错?花两分钟记录下来,帮助下一个遇到同样问题的开发者。

贡献一条解法