Java 11模块编译报错:--add-reads/--add-exports找不到moduleB的解决办法
解决Java 11模块化项目编译时
--add-reads和--add-exports的报错问题 我来帮你理清楚问题出在哪,以及怎么一步步解决:
首先分析报错根源:你之前编译moduleB的命令把编译产物直接放到了out/moduleB目录下,但Java模块化要求模块的编译产物必须放在以模块名命名的子目录里(比如out/modules/moduleB),否则javac通过-p指定模块路径时,找不到moduleB这个模块——这就是为什么会出现module name not found: moduleB的警告,后续的包找不到错误也都是因为这个核心问题。
接下来给你两种解决方案,推荐优先用标准模块化语法,临时调试可以用命令行选项:
一、推荐方案:使用模块化标准语法(显式声明依赖和导出)
这是Java模块化设计的标准用法,比临时命令行选项更清晰易维护:
- 修改moduleB的模块声明,导出目标包
修改moduleB/src/module-info.java,显式导出com.company.packageB包:
module moduleB { exports com.company.packageB; }
- 正确编译moduleB
将编译产物放到out/modules/moduleB目录下(保证模块结构符合规范):
javac -d out/modules/moduleB $(find moduleB/src -name "*.java")
- 修改moduleA的模块声明,添加依赖
修改moduleA/src/module-info.java,声明对moduleB的依赖:
module moduleA { requires moduleB; }
- 编译moduleA
通过-p指定包含所有模块的根目录out/modules:
javac -d out/modules/moduleA -p out/modules $(find moduleA/src -name "*.java")
二、临时调试方案:使用--add-reads和--add-exports命令行选项
如果不想修改模块声明文件,仅用于临时调试,可以按以下步骤操作:
- 先正确编译moduleB
同样要保证模块结构符合规范:
javac -d out/modules/moduleB $(find moduleB/src -name "*.java")
- 编译moduleA时指定正确的模块路径和命令行选项
这里的核心是-p要指向包含所有模块的根目录out/modules,让javac能找到moduleB:
javac -d out/modules/moduleA -p out/modules \ --add-reads moduleA=moduleB \ --add-exports moduleB/com.company.packageB=moduleA \ $(find moduleA/src -name "*.java")
补充说明
你之前的命令之所以报错,本质是模块路径的结构不符合Java模块化要求:编译后的模块必须放在[模块路径根目录]/[模块名]的结构下,而不是直接把class文件丢在模块路径根目录里。只要调整编译输出的目录结构,让javac能识别到moduleB模块,后续的权限配置就能正常生效。
内容的提问来源于stack exchange,提问作者wakedeer
相关产品推荐
相关产品推荐

