使用Maven-shade-plugin解决Spring Boot与HttpClient版本冲突问题
问题分析与解决方案
问题根源
你当前的maven-shade-plugin配置仅对org.springframework.http.client和org.apache.http做了包重定位,但编译阶段Foo组件的代码依然会引用项目依赖的Spring 6版本HttpComponentsClientHttpRequestFactory——这个版本的构造器参数已从CloseableHttpClient改为HttpClient,而Foo代码传入的是HttpClient 4的CloseableHttpClient,自然出现类型不匹配的编译错误。同时promoteTransitiveDependencies=true会把Foo的传递依赖(Spring 2.7、HttpClient4)提升到项目依赖中,反而加剧版本冲突。
修正后的Maven配置
1. 依赖管理锁定(避免编译阶段冲突)
先在dependencyManagement中明确Foo及其依赖的旧版本,并将旧版本Spring Boot、HttpClient4设为provided,避免干扰项目主代码的编译:
<dependencyManagement> <dependencies> <!-- 锁定Foo组件版本,并排除其自带的Spring Boot、HttpClient依赖 --> <dependency> <groupId>Foo</groupId> <artifactId>foo-artifact-id</artifactId> <version>你的Foo版本号</version> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </exclusion> <exclusion> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </exclusion> </exclusions> </dependency> <!-- 单独引入Foo需要的Spring Boot 2.7.18,设为provided --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.7.18</version> <scope>provided</scope> </dependency> <!-- 单独引入HttpClient4,设为provided --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.14</version> <scope>provided</scope> </dependency> </dependencies> </dependencyManagement>
2. 调整maven-shade-plugin配置
完整重定位Spring 2.7和HttpClient4的所有包,确保Foo组件在运行时完全使用隔离的旧版本依赖,同时关闭传递依赖提升:
<plugin> <artifactId>maven-shade-plugin</artifactId> <version>3.6.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <artifactSet> <!-- 包含Foo组件及其所需的旧版本依赖 --> <includes> <include>Foo:foo-artifact-id:*</include> <include>org.springframework.boot:spring-boot-starter-web:2.7.18</include> <include>org.apache.httpcomponents:httpclient:4.5.14</include> <include>org.apache.httpcomponents:httpcore:4.4.16</include> </includes> </artifactSet> <relocations> <!-- 重定位整个Spring 2.7包到shaded目录 --> <relocation> <pattern>org.springframework</pattern> <shadedPattern>shaded.org.springframework</shadedPattern> <excludes> <!-- 排除Spring Boot Loader相关类,避免和项目主版本冲突 --> <exclude>org.springframework.boot.loader.**</exclude> </excludes> </relocation> <!-- 重定位整个HttpClient4包到shaded目录 --> <relocation> <pattern>org.apache.http</pattern> <shadedPattern>shaded.org.apache.http</shadedPattern> </relocation> </relocations> <!-- 禁止提升传递依赖到项目依赖,避免冲突 --> <promoteTransitiveDependencies>false</promoteTransitiveDependencies> <createDependencyReducedPom>true</createDependencyReducedPom> <!-- 过滤确保只有指定的旧版本依赖被打包 --> <filters> <filter> <artifact>Foo:foo-artifact-id</artifact> <includes> <include>**/*</include> </includes> </filter> <filter> <artifact>org.springframework.boot:spring-boot-starter-web</artifact> <includes> <include>**/*</include> </includes> </filter> <filter> <artifact>org.apache.httpcomponents:httpclient</artifact> <includes> <include>**/*</include> </includes> </filter> </filters> </configuration> </execution> </executions> </plugin>
验证步骤
- 执行
mvn clean package编译打包 - 打开生成的Jar包,检查是否存在
shaded/org/springframework和shaded/org/apache/http目录 - 反编译Foo组件的类文件,确认其引用的
HttpComponentsClientHttpRequestFactory路径为shaded.org.springframework.http.client,而非项目主版本的路径
内容的提问来源于stack exchange,提问作者powerful_clouds
相关产品推荐
相关产品推荐

