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.