Java 9模块疑问:自定义无module-info库需JVM选项?求解决方案
Java 9自动模块使用疑问解答
核心原因
- 第三方库(如Guava)能直接当自动模块用,是因为它们的JAR包内置了
Automatic-Module-Name属性(在META-INF/MANIFEST.MF中)。Java 9+会自动识别这个属性,将JAR标记为自动模块,只要放在模块路径(module path)上,其他显式模块就能通过requires <模块名>直接引用。 - 你自己写的无
module-info.java的库,默认没有这个属性。如果把它放在classpath上,会被归为无名模块,而显式模块默认无法直接读取无名模块的内容,这时候就需要--upgrade-module-path这类参数将其升级为自动模块来打通依赖。
无需添加--upgrade-module-path的解决方案
1. 给自定义库添加Automatic-Module-Name属性(推荐)
不用编写module-info.java,只需在自定义库的META-INF/MANIFEST.MF中添加一行属性:
Automatic-Module-Name: com.your.custom.lib
如果用Maven构建,可通过插件自动生成该属性:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.3.0</version> <configuration> <archive> <manifestEntries> <Automatic-Module-Name>com.your.custom.lib</Automatic-Module-Name> </manifestEntries> </archive> </configuration> </plugin>
之后把这个JAR放在模块路径上,消费模块里用requires com.your.custom.lib;即可直接引用,无需额外JVM参数。
2. 将自定义JAR放在模块路径上
即使没有Automatic-Module-Name属性,Java会自动基于JAR文件名生成模块名(例如custom-lib-1.0.jar会被识别为custom.lib)。只需确保编译和运行时,把自定义JAR放在模块路径而非classpath上,消费模块里用requires <自动生成的模块名>;即可,不用额外参数。
注意:自动生成的模块名可能因文件名含版本号、特殊字符出现异常,建议优先用方案一指定明确模块名。
3. 让显式模块读取无名模块(不推荐)
如果坚持把自定义JAR放在classpath上,可通过JVM参数让消费模块读取无名模块:
--add-reads your.consumer.module.name=ALL-UNNAMED
这种方式会打破模块封装性,仅适合临时调试,不建议正式环境使用。
内容的提问来源于stack exchange,提问作者fade
相关产品推荐
相关产品推荐

