Using a RestTemplate or RestClient bean to make HTTP requests during warmup before creating a CRaC checkpoint using the jcmd myapp.jar JDK.checkpoint
command results in open socket exceptions when creating the checkpoint.
I have created a project on GitHub to reproduce the problem; see https://github.com/magnus-larsson/ml-spring-http-client-crac-error-demo.
The README.md
file contains instructions for how to reproduce the problem, but to summarise, run the following commands in a Linux environment with a Java 21 JDK that supports CRaC:
git clone https://github.com/magnus-larsson/ml-spring-http-client-crac-error-demo.git
cd ml-spring-http-client-crac-error-demo
./tests.bash
It will result in jdk.internal.crac.mirror.impl.CheckpointOpenSocketException
exceptions.
Comment From: sdeleuze
I expect it should work based on the lifecycle smoke test we have for that use case, but in order to make RestTemplate
lifecycle-aware you probably need create a RestTemplate
instance with an injected RestTemplateBuilder
or WebClient.Builder
in order to benefit from Spring Boot autoconfiguration.
I am not on Linux to please test that on your sample and let me know how it goes.
Comment From: magnus-larsson
Thanks for the suggestion!
I have verified that the lifecycle smoke test for a RestTemplate
, i.e. resttemplate-netty
, works in my Linux environment. The command ./gradlew :framework:resttemplate-netty:cRAT
runs successfully.
After that, my plan was to move my RestController
(that uses the RestTemplate
to make outgoing calls) from my project to the resttemplate-netty
project. But first, I had to enable the web server by removing the following line in RestTemplateApplication
:
application.setWebApplicationType(WebApplicationType.NONE);
But the app will not start after removing this line, complaining about:
Parameter 0 of method restTemplate in com.example.resttemplate.RestTemplateConfiguration required a bean of type 'org.springframework.boot.web.client.RestTemplateBuilder' that could not be found.
I don't understand why the RestTemplateBuilder
- bean no longer exists when enabling the web server.
Can you explain?
Comment From: sdeleuze
Indeed, not all underlying HTTP client engines are CRaC friendly, Netty should work for both RestTemplate
and WebClient
.
Sorry but Spring Framework bug tracker is probably not the best place to discuss such Spring Boot sample refinement. Maybe try it the other way by adding Reactor Netty dependency to your repro and use the builder.
I will close this issue as I think CRaC support is working as expected here (it requires by design a specific arrangement). If you are find an issue, please drop a comment and I will reopen this issue.
Comment From: magnus-larsson
Thanks for your help!
I managed to configure the RestTemplate
correctly so that the sockets are closed before the CRaC checkpoint is created.
For others who might stumble into the same problem, here is a summary of my resolution:
-
My understanding is that
WebFlux
does not provide an autoconfiguredRestTemplateBuilder
, so I had to switch back toWebMVC
. -
After adding a dependency to
spring-boot-starter-reactor-netty
, the sample configuration provided by the lifecycle smoke test worked out-of-the-box.
I have pushed a working solution for my project to the branch RestTemplateBuilder
. The README.md
file contains detailed instructions.
I have also added instructions to the README.md
file in both branches, main
and RestTemplateBuilder
, on how to run the samples on a Mac or Windows PC using a Docker container.