Open
Description
Description
When creating RestClient Bean with JdkClientHttpRequestFactory, like below
@Bean
public RestClient restClient(RestClient.Builder builder) {
return builder
.requestFactory(new JdkClientHttpRequestFactory())
.baseUrl(<baseUrl>)
.build();
}
Tests using @RestClientTest
and MockRestServiceServer
fail to connect.
Sample Application
https://github.com/williamsuane/failing-cat-fact/tree/master
Just execute the following test, as is
@RestClientTest({CatFactService.class})
class CatFactServiceTest {
@Autowired
private MockRestServiceServer server;
@Autowired
private CatFactService catFactService;
@Test
void test() {
server.expect(MockRestRequestMatchers.requestTo("http://localhost:8080/fact"))
.andRespond(MockRestResponseCreators.withSuccess("""
{"fact":"In 1987 cats overtook dogs as the number one pet in America."}
""", MediaType.APPLICATION_JSON));
var catFact = catFactService.getFact();
assertEquals("In 1987 cats overtook dogs as the number one pet in America.", catFact.fact());
}
}
it blows with the following exception
org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://localhost:8080/fact": null
at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.createResourceAccessException(DefaultRestClient.java:534)
at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.exchangeInternal(DefaultRestClient.java:459)
at org.springframework.web.client.DefaultRestClient$DefaultRequestBodyUriSpec.retrieve(DefaultRestClient.java:424)
at com.example.demo.CatFactService.getFact(CatFactService.java:17)
at com.example.demo.CatFactServiceTest.test(CatFactServiceTest.java:28)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
Caused by: java.net.ConnectException
at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:951)
at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:133)
at org.springframework.http.client.JdkClientHttpRequest.executeInternal(JdkClientHttpRequest.java:94)
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.DefaultRestClient$DefaultRequestBodyUriSpec.exchangeInternal(DefaultRestClient.java:453)
... 6 more
Caused by: java.net.ConnectException
at java.net.http/jdk.internal.net.http.common.Utils.toConnectException(Utils.java:1028)
at java.net.http/jdk.internal.net.http.PlainHttpConnection.connectAsync(PlainHttpConnection.java:227)
at java.net.http/jdk.internal.net.http.PlainHttpConnection.checkRetryConnect(PlainHttpConnection.java:280)
at java.net.http/jdk.internal.net.http.PlainHttpConnection.lambda$connectAsync$2(PlainHttpConnection.java:238)
at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:934)
at java.base/java.util.concurrent.CompletableFuture$UniHandle.tryFire(CompletableFuture.java:911)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run$$$capture(CompletableFuture.java:1773)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: java.nio.channels.ClosedChannelException
at java.base/sun.nio.ch.SocketChannelImpl.ensureOpen(SocketChannelImpl.java:202)
at java.base/sun.nio.ch.SocketChannelImpl.beginConnect(SocketChannelImpl.java:786)
at java.base/sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:874)
at java.net.http/jdk.internal.net.http.PlainHttpConnection.lambda$connectAsync$1(PlainHttpConnection.java:210)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:571)
at java.net.http/jdk.internal.net.http.PlainHttpConnection.connectAsync(PlainHttpConnection.java:212)
... 10 more
By removing the .requestFactory(new JdkClientHttpRequestFactory())
from
@Bean
public RestClient restClient(RestClient.Builder builder) {
return builder
.baseUrl(<baseUrl>)
.build();
}
The test works perfectly.