Spring Boot 3 TestRestTemplate sending null host to httpclient5

106 Views Asked by At

I'm migrating from Spring Boot 2 to 3. The same integration tests which used to work in 2.x, now do not work in 3.x. Example:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class DemoTest {
    
    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    public void demo() {
        ResponseEntity<String> response = restTemplate.getForEntity("/helloworld", String.class);
    }
}

fails with the following stack trace:


java.lang.NullPointerException: Target host
    at java.base/java.util.Objects.requireNonNull(Objects.java:233)
    at org.apache.hc.core5.util.Args.notNull(Args.java:169)
    at org.apache.hc.client5.http.impl.classic.MinimalHttpClient.doExecute(MinimalHttpClient.java:115)
    at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:87)
    at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:55)
    at org.apache.hc.client5.http.classic.HttpClient.executeOpen(HttpClient.java:183)
    at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:95)
    at org.springframework.http.client.AbstractStreamingClientHttpRequest.executeInternal(AbstractStreamingClientHttpRequest.java:70)
    at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:66)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:889)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:790)
    at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:431)
    at org.springframework.boot.test.web.client.TestRestTemplate.getForEntity(TestRestTemplate.java:245)

I've checked debug logs and TestRestTemplate definitely has a host URI at (for example) http://localhost:64877. But for some reason, once httpclient5 is executing, its host is null.

The dependency I gave in my build.gradle is implementation group: 'org.apache.httpcomponents.client5', name: 'httpclient5' //, version: '5.3.1'. I tried both with and without an explicit version, no change. I must be missing something obvious here, but I don't see it.

UPDATE: The cause turns out to be my custom RestTemplateCustomizer which is using HttpClients.createMinimal():

    @Bean
    public RestTemplateCustomizer customRestTemplateCustomizer() {
        return new RestTemplateCustomizer() {
            @Override
            public void customize(RestTemplate restTemplate) {
                restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(HttpClients.createMinimal()));
                restTemplate.setErrorHandler(new ApiResponseErrorHandler());
            }
        };
    }

If I remove the setRequestFactory line, or if I use createDefault() instead, it works. I don't know why.

0

There are 0 best solutions below