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:

  1. My understanding is that WebFlux does not provide an autoconfigured RestTemplateBuilder, so I had to switch back to WebMVC.

  2. 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.