Maven将其他模块置于classpath而非modulepath的修正方法
解决Maven多模块中JPMS自动模块依赖的编译问题
问题本质是Maven多模块构建的生命周期顺序导致的:当编译Module2时,Module1的package阶段还未执行,Maven默认会将Module1的target/classes目录加入classpath,而非打包后的jar——而JPMS自动模块要求依赖必须是jar形式存在于modulepath上,因此编译失败。
以下是可行的解决方案:
方案1:强制Module2编译前先打包Module1
在Module2的pom.xml中添加maven-invoker-plugin,在编译前触发Module1的打包操作,确保jar文件存在,再让编译器将其加入modulepath:
<build> <plugins> <!-- 确保使用支持JPMS的编译器版本 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.10.1</version> <configuration> <!-- 指定你的Java版本(需≥9) --> <release>11</release> <!-- 开启modulepath支持 --> <addModulepath>true</addModulepath> <useModulePath>true</useModulePath> </configuration> </plugin> <!-- 编译Module2前,先打包Module1 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-invoker-plugin</artifactId> <version>3.5.0</version> <executions> <execution> <id>pre-package-module1</id> <!-- 在编译前的阶段执行 --> <phase>generate-sources</phase> <goals> <goal>run</goal> </goals> <configuration> <!-- 指定Module1的pom路径 --> <pomFile>${project.parent.basedir}/module1/pom.xml</pomFile> <goals> <goal>package</goal> </goals> <!-- 跳过Module1的测试,加快构建 --> <skipTests>true</skipTests> </configuration> </execution> </executions> </plugin> </plugins> </build>
方案2:调整依赖方式,直接引用Module1的jar
如果方案1无效,可以尝试将Module2对Module1的依赖改为显式引用jar包,同时排除classes目录:
- 在Module2的
pom.xml中修改依赖定义:
<dependencies> <dependency> <groupId>${project.groupId}</groupId> <artifactId>module1</artifactId> <version>${project.version}</version> <!-- 强制使用jar类型 --> <type>jar</type> <!-- 排除默认的classes目录依赖 --> <exclusions> <exclusion> <groupId>${project.groupId}</groupId> <artifactId>module1</artifactId> <type>classes</type> </exclusion> </exclusions> </dependency> </dependencies>
- 配合编译器配置,确保jar被加入modulepath:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.10.1</version> <configuration> <release>11</release> <addModulepath>true</addModulepath> <compilerArgs> <!-- 显式指定modulepath包含Module1的jar --> <arg>--module-path</arg> <arg>${settings.localRepository}/${project.groupId}/module1/${project.version}/module1-${project.version}.jar</arg> </compilerArgs> </configuration> </plugin> </plugins> </build>
验证配置
执行父项目构建后,查看maven-compiler-plugin的输出,确认Module1的jar出现在Modulepath下,而非Classpath:
Modulepath: /path/to/myproject/module1/target/module1-v1.jar /path/to/other/jarFile1.jar /path/to/other/jarFile2.jar
内容的提问来源于stack exchange,提问作者Rich
相关产品推荐
相关产品推荐

