Java 17+Spring Boot 3.0.2启动报错:ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory
问题
使用Java 17 + Spring Boot 3.0.2启动应用时,出现以下启动错误:
Caused by: javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath. at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:278) ~[jaxb-api-2.3.1.jar:2.3.0] at javax.xml.bind.ContextFinder.find(ContextFinder.java:421) ~[jaxb-api-2.3.1.jar:2.3.0] at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:721) ~[jaxb-api-2.3.1.jar:2.3.0] at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:662) ~[jaxb-api-2.3.1.jar:2.3.0] at org.springframework.security.oauth2.http.converter.jaxb.AbstractJaxbMessageConverter.(AbstractJaxbMessageConverter.java:59) ~[spring-security-oauth2-2.5.1.RELEASE.jar:na] ... 60 common frames omitted Caused by: java.lang.ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[na:na] at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[na:na] at java.base/java.lang.Class.forName0(Native Method) ~[na:na] at java.base/java.lang.Class.forName(Class.java:467) ~[na:na] at org.springframework.boot.devtools.restart.classloader.RestartClassLoader.loadClass(RestartClassLoader.java:121) ~[spring-boot-devtools-3.0.2.jar:3.0.2] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[na:na] at javax.xml.bind.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:122) ~[jaxb-api-2.3.1.jar:2.3.0] at javax.xml.bind.ServiceLoaderUtil.safeLoadClass(ServiceLoaderUtil.java:155) ~[jaxb-api-2.3.1.jar:2.3.0] at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:276) ~[jaxb-api-2.3.1.jar:2.3.0]
应用上下文初始化时抛出org.springframework.beans.factory.UnsatisfiedDependencyException,导致启动失败,提示需启用debug模式查看条件评估报告。
现有pom.xml依赖配置
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>io.pivotal.spring.cloud</groupId> <artifactId>cloudfoundry-certificate-truster</artifactId> <version>1.0.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.9.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web-services</artifactId> <version>${spring.boot.version}</version> </dependency> <dependency> <groupId>org.springframework.ws</groupId> <artifactId>spring-ws-support</artifactId> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> </dependency> <!-- https://mvnrepository.com/artifact/jakarta.servlet/jakarta.servlet-api --> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>6.0.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>jakarta.xml.bind</groupId> <artifactId>jakarta.xml.bind-api</artifactId> <version>2.3.3</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>2.3.1</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-core</artifactId> <version>2.3.0.1</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> <version>3.23.1-GA</version> </dependency> <dependency> <groupId>org.apache.ant</groupId> <artifactId>ant</artifactId> <version>1.10.12</version> </dependency> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.19.1</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>${spring.data.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>${spring.boot.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.jayway.jsonpath</groupId> <artifactId>json-path</artifactId> </dependency> <dependency> <groupId>com.cloudbees</groupId> <artifactId>syslog-java-client</artifactId> <version>1.1.7</version> </dependency> <dependency> <groupId>com.sun.xml.ws</groupId> <artifactId>jaxws-ri</artifactId> <version>3.0.2</version> <type>pom</type> </dependency> <!-- HTML Sanitizer --> <dependency> <groupId>com.googlecode.owasp-java-html-sanitizer</groupId> <artifactId>owasp-java-html-sanitizer</artifactId> <version>20220608.1</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>6.0.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.20.0</version> </dependency> <dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> <version>2.5.1.RELEASE</version> </dependency>
原因分析
- JAXB实现缺失:Java 17已完全移除内置的JAXB实现(从Java 9开始标记为过时,Java 11正式移除),需要手动引入第三方实现。
- API包冲突:Spring Boot 3.x基于Jakarta EE规范,使用
jakarta.xml.bind包,但旧版spring-security-oauth2依赖的是javax.xml.bind,同时pom中同时引入了两套API,导致依赖混乱。 - 版本不兼容:
spring-security-oauth2 2.5.1.RELEASE已停止维护,不兼容Spring Boot 3.x和Java 17。
解决方案
1. 清理冲突的JAXB依赖
移除以下依赖:
javax.xml.bind:jaxb-apicom.sun.xml.bind:jaxb-corecom.sun.xml.bind:jaxb-impl
保留jakarta.xml.bind:jakarta.xml.bind-api,并替换为兼容Jakarta的JAXB实现:
<dependency> <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-runtime</artifactId> <version>4.0.3</version> <!-- 适配Jakarta API的最新稳定版 --> </dependency>
2. 替换Spring Security OAuth2
spring-security-oauth2 2.x已停止维护,建议迁移到Spring Security 6.x自带的OAuth2支持:
移除org.springframework.security.oauth:spring-security-oauth2,添加Spring Boot官方OAuth2 starter:
<!-- OAuth2客户端支持 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-client</artifactId> </dependency> <!-- OAuth2资源服务器支持(如果需要) --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-resource-server</artifactId> </dependency>
3. 清理Servlet API冲突
移除javax.servlet:javax.servlet-api,Spring Boot 3.x默认使用jakarta.servlet:jakarta.servlet-api,避免API版本冲突。
4. 统一依赖版本
尽量通过Spring Boot的parent依赖管理统一版本,减少手动指定版本带来的兼容性问题。例如spring-retry、aspectjweaver等可以移除手动版本号,由Spring Boot自动管理。
验证
修改完成后,执行mvn clean install清理并重新构建项目,启动应用检查错误是否解决。
内容的提问来源于stack exchange,提问作者amit mannur
相关产品推荐
相关产品推荐

