Description:

I am encountering a NullPointerException while trying to use the RestTemplate in combination with the MinimalHttpClient from the httpcomponents package to connect to external services. The error occurs when executing a request.

Steps to Reproduce:

Observed Behavior:

The error is thrown from the spring-web module, specifically in the method HttpComponentsClientHttpRequest#executeInternal.

Stack Trace:

java.lang.NullPointerException: Target host
    at java.base/java.util.Objects.requireNonNull(Objects.java:259) ~[na:na]
    at org.apache.hc.core5.util.Args.notNull(Args.java:165) ~[httpcore5-5.3.5.jar:5.3.5]
    at org.apache.hc.client5.http.impl.classic.MinimalHttpClient.doExecute(MinimalHttpClient.java:113) ~[httpclient5-5.5.jar:5.5]
    at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:87) ~[httpclient5-5.5.jar:5.5]
    at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:55) ~[httpclient5-5.5.jar:5.5]
    at org.apache.hc.client5.http.classic.HttpClient.executeOpen(HttpClient.java:183) ~[httpclient5-5.5.jar:5.5]
    at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:99) ~[spring-web-7.0.0-M9.jar:7.0.0-M9]
    at org.springframework.http.client.AbstractStreamingClientHttpRequest.executeInternal(AbstractStreamingClientHttpRequest.java:70) ~[spring-web-7.0.0-M9.jar:7.0.0-M9]
    at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:80) ~[spring-web-7.0.0-M9.jar:7.0.0-M9]
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:754) ~[spring-web-7.0.0-M9.jar:7.0.0-M9]
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:677) ~[spring-web-7.0.0-M9.jar:7.0.0-M9]
    at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:304) ~[spring-web-7.0.0-M9.jar:7.0.0-M9]

Possible Cause:

It seems like the error is triggered by the MinimalHttpClient in the httpclient5 library, specifically when the target host is not provided or is null during the execution of the request. The issue appears to originate from the internal request execution in HttpComponentsClientHttpRequest.

Environment:

  • Spring Web: 7.0.0-M9
  • HttpClient: 5.5
  • HttpCore: 5.3.5

Additional Information:

  • I have confirmed that the error occurs with the minimal example provided.
  • Any insights into why this issue might be happening would be greatly appreciated.

Comment From: ojas-krishnaprasad

In HttpComponentsClientHttpRequest#executeInternal

// Original Code:
this.httpClient.executeOpen((HttpHost) null, this.httpRequest, this.httpContext);

// Proposed Code:
this.httpClient.executeOpen(RoutingSupport.determineHost(this.httpRequest), this.httpRequest, this.httpContext);

Comment From: rstoyanchev

This is a question to raise Apache HttpComponents. Is it intentional and if so is there a reason not to do it? If it is not intentional, then a fix in the library itself is more appropriate, and it would have a wider reach.

Closing for now, but feel free to comment with further findings.

Comment From: ojas-krishnaprasad

@rstoyanchev The Spring class HttpComponentsClientHttpRequest is calling an Apache HttpComponents method with a null parameter, which is causing the problem. This issue seems to have been introduced with Spring 6, at least.

And the PR here

Comment From: bclozel

@ojas-krishnaprasad per HttpComponents Javadoc:

target - the target host for the request. Implementations may accept null if they can still determine a route, for example to a default target or by inspecting the request.

We never intended to support MinimalHttpClient and we don't test against it. The PR is proposing a change but with no test attached, so it's very likely to be declined.

Comment From: rstoyanchev

The first place to consider for a fix is MinimalHttpClient. It has everything necessary, and as the Javadoc says, null is acceptable as input if the information is possible to extract.