JPMS环境下Maven构建引用依赖模块主类失败问题咨询
关于JPMS模块化Maven项目指定外部模块主类构建失败的问题解答
核心结论
- 这是maven-jar-plugin的限制,而非JPMS本身的强制要求
- ModulePackages是JDK自动生成的属性,无需手动定义
- JPMS允许调用外部模块主类,但maven-jar-plugin要求模块化JAR的主类必须属于自身模块
详细解释
1. 是JPMS限制还是配置遗漏?
这不是JPMS的限制——JPMS支持通过java --module <依赖模块>/<主类全限定名>的方式直接运行其他模块的主类。但maven-jar-plugin在构建可执行模块化JAR时,会额外校验主类所在的包必须属于当前模块(通过ModulePackages属性验证),因为插件默认认为模块化JAR的入口类应该归属于自身模块,所以当你指定外部模块的主类时,插件会抛出校验错误。
2. ModulePackages类文件属性应定义在何处?
ModulePackages是JDK的jar工具在处理module-info.java时,自动生成并写入JAR的MANIFEST.MF中的属性,它的作用是记录当前模块包含的所有包路径。这个属性不需要手动定义,完全由JDK根据当前模块的module-info.java和实际编译后的包结构自动生成。
你遇到的报错“包a.b.c.d缺失ModulePackages类文件属性”,本质是因为这个包属于依赖模块,而非当前模块,所以当前模块的ModulePackages里不包含这个包,maven-jar-plugin校验时判定主类所在包不属于当前模块,从而报错。
3. 是否模块化JAR的主类必须为自身模块类,或是maven-jar-plugin的限制?
- JPMS本身无此限制:你可以直接通过命令行运行其他模块的主类,例如:
java --module your.dependency.module/a.b.c.d.MainClass - maven-jar-plugin有此限制:插件在构建可执行模块化JAR时,要求主类必须属于当前模块,否则会触发校验失败。这是插件的设计逻辑,目的是保证模块化JAR的入口类与自身模块的一致性。
解决办法
- 推荐方案:在当前模块中创建一个自定义Main类,作为入口调用依赖模块的主类,例如:
然后在maven-jar-plugin中配置这个类为package your.current.module; public class Main { public static void main(String[] args) { a.b.c.d.MainClass.main(args); } }<mainClass>,这样既符合插件要求,也能正常调用依赖模块的功能。 - 非推荐方案:如果一定要跳过插件校验,可以尝试手动在MANIFEST.MF中指定Main-Class,但这可能导致模块化运行时的类加载问题,不建议在生产环境使用。
内容的提问来源于stack exchange,提问作者R...
相关产品推荐
相关产品推荐

