根本原因是模块图未授权访问java.sql等模块,需在module-info.java中显式声明requires java.sql;等对应依赖,否则即使类存在也会报cannot find symbol。

这个问题通常出现在使用 Java 9+ 模块系统(JPMS)的项目中,“requires 声明缺失”不是直接报“找不到符号”,而是间接引发该错误——比如你明明写了 import java.sql.Connection;,编译却报 cannot find symbol: class Connection。根本原因不是类不存在,而是模块图未授权当前模块访问 java.sql 这个模块,导致其导出的包对你的代码不可见。
确认是否处于模块化环境
先看项目根目录是否有 module-info.java 文件。如果有,且其中没有声明 requires java.sql;(或对应所需模块),那大概率就是它。常见被忽略的模块包括:
-
java.sql(JDBC 相关类) -
java.xml(DOM、SAX 等) -
java.desktop(Swing、AWT) - 第三方模块(如
org.apache.commons.logging)需确保其已声明为自动模块或有正确module-info.java
检查 module-info.java 中的 requires 语句
打开 module-info.java,逐行核对:
- 是否漏写了所需模块?例如用了
LocalDateTime却没写requires java.time;(注意:java.base自动隐式依赖,不用写;但java.time属于java.base,所以其实也不用显式 requires —— 这里只是举例逻辑) - 是否拼写错误?
requires java.se;是错的,正确是requires java.sql;或requires java.desktop; - 是否用了
requires static?该修饰符表示仅编译期需要,运行时可选。如果你的代码在运行时也用到了该模块(比如真调用了DriverManager.getConnection()),就不能只写static
验证模块导出与可读性
即使写了 requires xxx;,若目标模块未导出对应包,仍会“找不到符号”。例如:
-
java.sql模块导出了java.sql包,所以requires java.sql;+import java.sql.Connection;是合法的 - 但某个自定义模块
com.example.util若没在自己的module-info.java中写exports com.example.util;,那么即使你requires com.example.util;,也无法 import 其中的类
可通过 javap --module java.sql --show-module 查看模块导出信息(JDK 自带模块大多导出明确,重点查自研或第三方模块)。
临时绕过模块限制快速验证
如果怀疑是模块配置问题,可在编译时加参数跳过模块检查,确认是否为根源:
- 命令行编译:
javac --add-modules java.sql YourClass.java - Maven 项目:在
pom.xml的maven-compiler-plugin配置中添加--add-modules java.sql - IDEA:File → Project Structure → Modules → Dependencies → 点 “+” → “Module Dependency” 或 “JDK Module Dependency”
若加了 --add-modules 后编译通过,基本锁定是 requires 缺失或模块图不完整。









