You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 23:46:09