Spring启动报NoClassDefFoundError: jakarta/xml/bind/JAXBException排查
已安装全部所需依赖的情况下仍无法正常启动Spring应用,项目pom.xml依赖配置如下:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.20</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.3.20</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.3.20</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.3.20</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.20</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.3.20</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <version>2.7.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> <version>3.1.0.M2</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>6.0.2.Final</version> </dependency> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>7.0.4.Final</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> <version>5.7.1</version> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-runtime</artifactId> <version>4.0.0</version> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.3.6</version> </dependency> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring5</artifactId> <version>3.0.15.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> <version>2.7.0</version> </dependency>
运行时抛出异常信息如下:
org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: jakarta/xml/bind/JAXBException
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1082)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:94)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Root Cause
java.lang.NoClassDefFoundError: jakarta/xml/bind/JAXBException
org.hibernate.boot.cfgxml.internal.ConfigLoader$1.initialize(ConfigLoader.java:41)
org.hibernate.boot.cfgxml.internal.ConfigLoader$1.initialize(ConfigLoader.java:38)
org.hibernate.internal.util.ValueHolder.getValue(ValueHolder.java:55)
org.hibernate.boot.cfgxml.internal.ConfigLoader.loadConfigXmlResource(ConfigLoader.java:57)
org.hibernate.boot.registry.StandardServiceRegistryBuilder.configure(StandardServiceRegistryBuilder.java:244)
org.hibernate.cfg.Configuration.configure(Configuration.java:296)
org.hibernate.cfg.Configuration.configure(Configuration.java:281)
Konstantin.Game.MVC.config.HibernateUtilConfig.getSessionFactory(HibernateUtilConfig.java:16)
Konstantin.Game.MVC.DAO.GameDAO.findAll(GameDAO.java:43)
Konstantin.Game.MVC.controllers.GameController.index(GameController.java:27)
java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
java.base/java.lang.reflect.Method.invoke(Method.java:577)
已参考同类问题解决方案,尝试添加如下依赖:
<dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-runtime</artifactId> <version>4.0.0</version> </dependency>
问题仍未解决。
更新:
- 已补充运行错误相关截图。
报错核心是javax和jakarta两套EE规范依赖混装不兼容,不是单纯缺类:
- 你当前用的Spring 5.3.x、Spring Boot 2.7.x、thymeleaf-spring5、javax.servlet-api全部基于旧Java EE规范,类路径前缀是
javax.* - 但引入的Hibernate 6.0.2.Final、Thymeleaf 3.1.0.M2、jaxb-runtime 4.0.0全部基于Jakarta EE 9+新规范,类路径前缀是
jakarta.*,两套规范的包名完全不互通。你加的旧javax包下的JAXB类,Hibernate 6根本识别不到,启动时只会找jakarta路径下的JAXBException类,自然报类找不到错误。
二选一即可,不要混用两套生态的依赖。
方案1(推荐,改动最小,适配现有Spring生态)
把所有Jakarta新规范的依赖降级到适配javax规范的稳定版本,统一全项目依赖的包前缀:
- 替换Hibernate依赖,从6.x降到最后一个支持javax规范的5.6.x稳定版:
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.6.14.Final</version> </dependency>
- 删除单独引入的thymeleaf 3.1.0.M2里程碑版本(本身不稳定,且属于Jakarta生态),只保留和Spring5适配的thymeleaf-spring5 3.0.15.RELEASE即可,避免版本冲突。
- 替换JAXB相关依赖,把jaxb-runtime从4.0.0降到适配javax规范的2.3.x版本:
<dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-runtime</artifactId> <version>2.3.6</version> </dependency>
- 刷新Maven依赖,清理target目录下旧编译文件后重新启动即可。
方案2(全量升级到Jakarta生态,改动较大)
如果必须使用Hibernate 6新特性,就把全项目依赖升级到支持Jakarta规范的版本:
- Spring框架升级到6.x版本,Spring Boot升级到3.x版本
- thymeleaf-spring5替换为thymeleaf-spring6
- javax.servlet-api替换为jakarta.servlet-api 5.0+版本
- hibernate-validator同步升级到适配Jakarta EE的版本
- 注意Spring 6和Spring Boot 3最低要求JDK 17版本,升级前先确认运行环境符合要求。
如果改完版本仍有报错,执行mvn dependency:tree查看全量依赖树,排查是否有其他传递依赖引入了冲突的javax/jakarta包版本,手动在对应依赖下排除冲突项即可。
内容的提问来源于stack exchange,提问作者Федоченко Леонид

