Java 9中从模块类调用非模块类遇moduleC未找到错误求助
我来帮你一步步排查和解决这个问题,你的核心问题有两个:一是JVM识别不到moduleC模块,二是模块类无法访问非模块类的权限限制问题。
一、先搞定「moduleC not found」错误
这个错误基本是因为编译后的moduleC目录里缺少module-info.class,JVM没法把它当成合法模块识别。你之前的编译命令可能没把module-info.java一起编译进去,按下面的步骤重新编译:
先确认你的源代码结构是否和下面一致(这是模块系统要求的标准结构):
moduledemo/ ├─ moduleC/ │ ├─ module-info.java # 模块描述文件必须在模块根目录! │ └─ packageC/ │ └─ MyMethods.java └─ nomodule/ └─ packageD/ └─ DemoNoModule.java
执行这个编译命令,把模块的所有代码(包括module-info.java)编译到allclasses目录:
javac -d allclasses moduleC/module-info.java moduleC/packageC/MyMethods.java
编译完成后,去allclasses/moduleC目录下看看,应该能找到module-info.class和packageC/MyMethods.class,这时候JVM就能识别moduleC是个合法模块了。
二、解决模块访问非模块类的权限问题
Java 9的模块系统有严格的访问控制,模块默认不能直接读取类路径上的「未命名模块」(也就是你的非模块类),所以得做两个调整:
1. 临时方案:调整运行命令
运行时加上参数让moduleC能读取未命名模块的内容,命令如下:
java --module-path allclasses --class-path nomodule --add-reads moduleC=ALL-UNNAMED -m moduleC/packageC.MyMethods
参数解释:
--module-path allclasses:告诉JVM模块的存放路径(这里就是moduleC所在的位置)--class-path nomodule:把非模块类所在的nomodule目录加到类路径,作为未命名模块--add-reads moduleC=ALL-UNNAMED:允许moduleC读取未命名模块里的所有类-m moduleC/packageC.MyMethods:指定要运行的模块主类
2. 永久方案:修改module-info.java
如果不想每次运行都加--add-reads,可以直接在moduleC的module-info.java里声明依赖未命名模块:
module moduleC { exports packageC; requires static ALL-UNNAMED; // 新增这一行,声明读取未命名模块 }
之后运行命令就可以简化成:
java --module-path allclasses --class-path nomodule -m moduleC/packageC.MyMethods
三、验证结果
执行正确的命令后,你应该能看到预期输出:
this is show of D in No Module
最后再提醒下:module-info.java必须放在模块的根目录下(也就是moduleC/文件夹里,不能放到packageC里),这是Java模块系统的硬性要求,放错位置的话模块也会识别失败。
内容的提问来源于stack exchange,提问作者user2779311

