基于ArtifactVersionCollector从POM获取多模块版本的Jar运行异常问题
多模块Java项目打包后版本获取异常问题
我在IntelliJ中配置了一个包含多个子模块的Java应用(Java子模块未命名),每个子模块根目录都有独立的POM文件,编译正常。目标是让每个子模块通过ArtifactVersionCollector获取自身版本,代码示例如下:
import de.westemeyer.version.service.ArtifactVersionCollector; class Main { static String getVersion(){ String modname = "Main"; return modname + ":" + ArtifactVersionCollector.findArtifact("com.dds.project",modname); } public static void main(String[] argv){ for(var v : artifactVersionCollector.collectArtifacts().toArray()){ sLogger.error( "{}", v ); } } } class Prj2 { static String getVersion(){ String modname = "prj2"; return modname + ":" + ArtifactVersionCollector.findArtifact("com.dds.project",modname); } } class Prj3 { static String getVersion(){ String modname = "prj3"; return modname + ":" + ArtifactVersionCollector.findArtifact("com.dds.project",modname); } }
目前在IntelliJ中以Java应用运行可正常获取各版本,但通过mvn clean package打包成Jar后(运行目录与IntelliJ配置一致),仅能获取单个组件的版本,例如在Main.java中调用仅返回prj3的版本。
项目结构如下:
base | - prj1 --src --- Main.java --pom.xml (Main:V1) - prj2 --src --- File2.java --pom.xml (prj2:V2) - prj3 --src --- File3.java --pom.xml (prj3:V3) - pom.xml (base:va) <== 该POM包含modules节点
问题原因
ArtifactVersionCollector依赖Maven生成的pom.properties或MANIFEST.MF文件读取版本信息。打包后出现单版本覆盖的核心原因是:
- 多子模块的版本信息文件被打包到Jar内同一路径,后打包的模块文件覆盖了先打包的;
- 代码中指定的模块名与子模块POM里的
artifactId不匹配,导致工具无法定位对应模块的版本,最终只能读取到最后加载的版本文件。
解决方案
1. 统一模块名与POM的artifactId
每个子模块的pom.xml必须明确配置artifactId,且与代码中modname完全一致:
- prj1的pom.xml示例:
<project> <groupId>com.dds.project</groupId> <artifactId>Main</artifactId> <!-- 与代码中modname一致 --> <version>V1</version> ... </project>
- prj2的pom.xml示例:
<project> <groupId>com.dds.project</groupId> <artifactId>prj2</artifactId> <!-- 与代码中modname一致 --> <version>V2</version> ... </project>
2. 用Maven Shade插件避免资源冲突
若打包成Fat Jar,需通过Shade插件合并版本信息文件,防止覆盖:
在父POM或负责打包的模块POM中添加配置:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.4.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <!-- 合并各子模块的pom.properties --> <transformer implementation="org.apache.maven.plugins.shade.resource.PropertiesAppendingTransformer"> <resource>META-INF/maven/com.dds.project/Main/pom.properties</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.PropertiesAppendingTransformer"> <resource>META-INF/maven/com.dds.project/prj2/pom.properties</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.PropertiesAppendingTransformer"> <resource>META-INF/maven/com.dds.project/prj3/pom.properties</resource> </transformer> <!-- 配置主类(按需添加) --> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>Main</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build>
3. 验证打包结果
打包完成后解压Jar,检查META-INF/maven/com.dds.project目录下是否存在每个子模块的独立文件夹,且内部pom.properties的版本信息正确无覆盖。
内容的提问来源于stack exchange,提问作者DDS
相关产品推荐
相关产品推荐

