Java 9环境下Spring MVC+Spring Boot+Gradle项目运行报错求助
解决JPMS模块系统下Spring应用运行报错的问题
我之前也碰到过类似的情况——原本在Java 8下好好的Spring应用,加了module-info.java后编译过了,一运行就炸。咱们来一步步拆解问题,解决它:
先搞清楚核心原因
Java 8本身不支持模块系统(JPMS),这是Java 9才引入的特性。你现在的情况要么是用JDK 9+编译带模块声明的代码,然后在Java 8上运行(兼容性冲突);要么是用JDK 9+运行,但模块配置没做好,导致Spring无法正常反射访问类、依赖的JDK模块没声明。
方案1:如果要继续在Java 8环境运行(最省心)
直接删掉module-info.java文件!Java 8的JVM根本识别不了这个文件,强行加只会给类加载添乱。删掉之后,回到原来的类路径模式,你的应用就能正常跑了。
方案2:升级到JDK 9+运行,正确配置模块
如果你打算切换到支持JPMS的JDK版本,那需要把module-info.java配置对,不然Spring的反射机制会被模块系统限制住:
1. 修正module-info.java
假设你的应用模块名叫com.example.demo,主类和Controller在com.example.demo和com.example.demo.controller包下,那模块声明应该这么写:
module com.example.demo { // 声明依赖的Spring核心模块(根据你的Spring版本调整) requires spring.context; requires spring.web; requires spring.boot; requires spring.boot.autoconfigure; // 导出你的包,让Spring能扫描到Bean exports com.example.demo; exports com.example.demo.controller; // 开放包给Spring反射访问(必须!Spring需要创建实例、处理注解) opens com.example.demo to spring.context, spring.boot; opens com.example.demo.controller to spring.web, spring.context; // 声明依赖JDK的java.sql模块,解决NoClassDefFoundError问题 requires java.sql; }
2. 调整Gradle配置适配模块系统
在build.gradle里确保JDK版本和模块路径配置正确:
plugins { id 'java' id 'org.springframework.boot' version '2.7.15' // 选兼容JDK 8+的Spring Boot版本 id 'io.spring.dependency-management' version '1.0.15.RELEASE' } group = 'com.example' version = '0.0.1-SNAPSHOT' java { sourceCompatibility = '1.8' targetCompatibility = '1.8' // 自动推断模块路径,适配JPMS modularity.inferModulePath = true } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('test') { useJUnitPlatform() } // 如果运行时还是有反射权限问题,添加JVM参数 tasks.named('run') { jvmArgs = [ '--add-opens', 'java.base/java.lang=org.springframework.context', '--add-opens', 'java.base/java.util=org.springframework.context' ] }
为啥会报那两个错?
java.lang.NoClassDefFoundError: java/sql/SQLException:JPMS下模块默认不能访问其他模块的类,哪怕是JDK自带的java.sql模块,必须显式声明requires java.sql;才能用。Cannot instantiate interface org.springframework.conte...:Spring依赖反射创建Bean、处理注解,但你的模块没开放对应的包给Spring,模块系统把反射权限给拦住了,所以Spring没法实例化上下文对象。
内容的提问来源于stack exchange,提问作者Bogdan Timofeev
相关产品推荐
相关产品推荐

