Java 9环境下Spring Boot模块找不到错误求助
这个问题的核心在于Spring Boot 2.0.x版本对Java模块系统(JPMS)的支持非常有限——早期的Spring Boot 2.0系列发布时,JPMS刚推出不久,大部分Spring生态的JAR包还没有包含module-info.class,导致在模块路径下运行时,这些JAR会被当作「自动模块」,但自动模块的命名规则和你手动声明的requires可能不匹配,同时Spring Boot的自动配置逻辑也没有适配模块环境。
下面是具体的解决方案,按优先级排序:
1. 优先升级Spring Boot版本(最推荐)
Spring Boot从2.1.x版本开始,对JPMS提供了官方支持,核心模块(比如spring-boot-autoconfigure、spring-boot-starter-web等)都添加了正式的module-info.class,能完美兼容Java 9+的模块系统。
修改你的pom.xml中的父依赖版本为2.1.x的LTS版本(比如2.1.18.RELEASE):
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.18.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent>
升级后,你需要调整module-info.java的requires声明,使用Spring官方定义的模块名称,示例如下:
module com.journaldev.spring.SpringWebflux { // Spring WebFlux核心依赖 requires reactor.core; requires spring.webflux; // Spring Boot核心自动配置 requires spring.boot; requires spring.boot.autoconfigure; // Spring上下文依赖 requires spring.context; // 开放你的应用包给Spring,让它能创建代理类(必要时添加) opens com.journaldev.spring.SpringWebflux to spring.core, spring.context; // 如果有控制器等需要Spring扫描的组件,导出对应的包 exports com.journaldev.spring.SpringWebflux.controller; }
2. 若无法升级,适配自动模块规则
如果暂时不能升级到2.1+,你需要根据自动模块的命名规则调整requires声明:自动模块的名称是从JAR文件名生成的,将连字符替换为点,去掉版本号。
比如spring-boot-autoconfigure-2.0.1.RELEASE.jar对应的自动模块名是spring.boot.autoconfigure,你需要在module-info.java中添加:
requires spring.boot.autoconfigure; requires spring.boot.starter.web; // 如果用了web starter
另外需要注意:Spring Boot 2.0.x在模块环境下的自动配置可能存在一些兼容性问题,比如某些自动配置类无法被扫描到,这种情况下可能需要手动配置部分Bean,或者考虑暂时放弃模块系统。
3. 临时方案:关闭模块系统
如果你的应用不需要严格遵循JPMS规范,可以直接删除module-info.java,让应用运行在类路径下(而非模块路径),这样Spring Boot的自动配置逻辑就能正常工作,不会出现模块找不到的问题。
内容的提问来源于stack exchange,提问作者Pankaj

