Maven多模块中如何为不同模块使用同一依赖的不同版本?
父子模块分别使用同一依赖不同版本的解决方案
可行性说明
完全可行,但直接在子模块声明不同版本大概率会被依赖管理机制覆盖——比如Maven的依赖调解规则、Gradle的版本冲突处理逻辑,都会优先使用父模块传递过来的版本1,这就是你看到类路径有两个版本但实际只用版本1的原因。
具体实现方式
Maven 环境
- 先在子模块B的
pom.xml中,排除父模块传递的版本1依赖,再显式引入版本2:
<!-- 模块B的pom.xml --> <dependencies> <dependency> <groupId>依赖的groupId</groupId> <artifactId>依赖的artifactId</artifactId> <version>2.x.x</version> <!-- 排除父模块传递过来的版本1 --> <exclusions> <exclusion> <groupId>依赖的groupId</groupId> <artifactId>依赖的artifactId</artifactId> </exclusion> </exclusions> </dependency> </dependencies>
- 如果父子模块最终会打包到同一个产物(比如war包),类路径仍会出现冲突,这时候要用
maven-shade-plugin对模块B的版本2依赖做类重定位,修改其包路径避免和版本1的类冲突:
<!-- 模块B的pom.xml中配置shade插件 --> <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> <relocations> <relocation> <pattern>原依赖包路径</pattern> <shadedPattern>重命名后的包路径(比如原路径加.v2后缀)</shadedPattern> </relocation> </relocations> </configuration> </execution> </executions> </plugin> </plugins> </build>
Gradle 环境
- 在子模块B的
build.gradle中,排除父模块传递的依赖后引入版本2:
// 模块B的build.gradle dependencies { implementation('依赖的groupId:依赖的artifactId:2.x.x') { exclude group: '依赖的groupId', module: '依赖的artifactId' } }
- 若打包后类路径冲突,使用
shadow插件做类重定位:
plugins { id 'com.github.johnrengelman.shadow' version '7.1.2' } shadowJar { relocate '原依赖包路径', '重命名后的包路径(比如原路径加.v2后缀)' }
核心注意事项
- 依赖解析机制会优先选择路径更短、声明更早的版本,父模块的依赖通常会被优先选用,因此必须主动排除父模块传递的版本。
- 类重定位是解决同包类冲突的关键,JVM加载类时只会取类路径中第一个找到的类文件,重定位后两个版本的类处于不同包路径,不会互相覆盖。
- 如果模块A和模块B是独立运行的产物(比如两个独立jar包),不需要类重定位,各自声明对应版本即可正常使用。
内容的提问来源于stack exchange,提问作者Seri
相关产品推荐
相关产品推荐

