Java8升Java11后IntelliJ提示javax.smartcardio不在模块图但编译正常
为什么Maven编译运行正常,IntelliJ却标红
Java 9 开始引入的JPMS模块系统中,java.smartcardio属于JDK内置但未被纳入java.se核心聚合模块的非核心模块。
当项目没有module-info.java、使用传统类路径(无名模块)模式时:
- 运行阶段:JVM默认会将所有JDK内置模块全部加入模块图,并对无名模块开放所有包,所以功能运行完全正常。
- Maven编译阶段:你当前使用的Spring Boot父pom或者项目maven-compiler-plugin的生效配置中,已经隐式添加了
--add-modules java.smartcardio的编译参数,所以编译不会报错。 - IntelliJ的代码检查是独立于Maven的自有逻辑,很多时候如果Maven的编译参数没有被IDEA正确同步识别,就会出现代码检查报错但实际Maven构建正常的情况。
遗漏的配置是什么
你只是没有将--add-modules java.smartcardio显式配置到项目pom的maven-compiler-plugin中,仅在IDEA本地设置添加的话,配置只对本地环境生效,也不会被IDEA自动关联到项目的Maven配置上。
显式配置的参考示例:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>11</source> <target>11</target> <compilerArgs> <arg>--add-modules</arg> <arg>java.smartcardio</arg> </compilerArgs> </configuration> </plugin>
添加后刷新IDEA的Maven项目,标红会自动消失,不需要单独改IDEA的本地配置。
编译时是否必须添加该模块
是的,只要你使用javax.smartcardio相关类,编译阶段就必须显式添加该模块。因为javac在类路径模式下默认只会加载java.se核心模块下的类,非核心模块必须通过--add-modules显式引入才会被编译期识别。
你当前Maven编译没有报错,就是因为已经有隐式的配置添加了该参数,不需要你手动额外处理。
如何确认Maven的相关配置
你可以执行mvn help:effective-pom命令查看项目生效的完整pom配置,搜索maven-compiler-plugin的相关参数,就能看到已经生效的--add-modules相关配置,可能是直接引入了java.smartcardio,也可能是配置了ALL-SYSTEM(自动引入所有JDK内置模块)。
你不使用module-info.java的选择是符合当前Spring Boot生态现状的,目前绝大多数Spring Boot项目都还是使用传统类路径模式,不需要引入JPMS模块配置。
内容的提问来源于stack exchange,提问作者Sebastian Riemer

