My project used to have a dependency on spring-boot 2.7.18. I'm now in the process of bumping that to 3.3.5. My project also depends on Foo, which depends on spring-boot 2.7.18. As you can tell, there's a conflict in spring-boot versions (3.3.5 vs 2.7.18).
Also, my project used to depend on httpclient 4. Now that I'm bumping my spring-boot version, Spring gets bumped from 5 to 6. Spring 6 requires httpclient 5. Therefore, I'm also bumping my httpclient version from 4 to 5. However, Foo depends on httpclient 4. Yet again, there's a conflict in httpclient versions (4.x vs 5.x)
I'm trying to address both of those dependency version mismatches using the maven-shade plugin. I want Foo to keep using spring-boot 2.7.18 and httpclient 4 while my project uses spring-boot 3.3.5 and httpclient 5.
Somewhere in Foo, there's the following code
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
...
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslSocketFactory).build();
restTemplateBuilder = restTemplateBuilder.requestFactory(() -> new HttpComponentsClientHttpRequestFactory(httpClient));
I see the following compile-time error in IntelliJ:
Required type: HttpClient
Provided type: CloseableHttpClient
That's because the signature of the HttpComponentsClientHttpRequestFactory
constructor has changed from accepting a CloseableHttpClient
instance to accepting an HttpClient
instance.
As I said, I'm trying to use the maven-shade plugin to resolve the dependency version mismatch. Here's the relevant section of pom.xml
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>Foo</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>org.springframework.http.client</pattern>
<shadedPattern>shaded.org.springframework.http.client</shadedPattern>
</relocation>
<relocation>
<pattern>org.apache.http</pattern>
<shadedPattern>shaded.org.apache.http</shadedPattern>
</relocation>
</relocations>
<promoteTransitiveDependencies>true</promoteTransitiveDependencies>
<createDependencyReducedPom>true</createDependencyReducedPom>
</configuration>
</execution>
</executions>
</plugin>
Unfortunately, I'm still seeing the same error. This is my first time using the maven-shade plugin. Can you please help me figure out how I need to configure the pom.xml to resolve the issue?
Fyi I'm using Java 21.
It turns out that the httpclient version mismatch wasn't the actual problem. Since httpclient 4 and httpclient 5 are in different namespaces, no shading was required there.
The actual problem was the spring version mismatch caused by the spring-boot version bump. That's what I needed to address.
At first, I tried to shade org.springframework in the root project's pom.xml (let's call the root project Qux). However, I eventually realized that it wasn't possible to do so because I can't have both spring-boot 2 and spring-boot 3 on the same classpath. Therefore, either Qux would fail because spring-boot 2 was on the classpath or Foo would fail because spring-boot 3 was on the classpath, and all my shading was in vain.
Finally, I realized that I have to perform the shading in Foo's pom.xml. Since I didn't have direct access to Foo's source code, I created 2 new modules via IntelliJ: a parent one and Bar. Bar has a dependency on Foo. I shaded org.springframework in Bar's xml. In the parent pom.xml, I added Bar and Qux to the section. Now, everything works like a charm.