Describe the bug I have a very simple demo app running Config Server, Eureka, a Hello Service, and a Hello-App on localhost. After updating to Spring Boot 3.4 and Cloud 2024RC1 the app throws at startup:
2024-11-27T10:28:20.014+01:00 INFO 35724 --- [hello-application] [ restartedMain] DiscoveryClientOptionalArgsConfiguration : Eureka HTTP Client uses RestClient.
2024-11-27T10:28:20.030+01:00 WARN 35724 --- [hello-application] [ restartedMain] iguration$LoadBalancerCaffeineWarnLogger : Spring Cloud LoadBalancer is currently working with the default cache. While this cache implementation is useful for development and tests, it's recommended to use Caffeine cache in production.You can switch to using Caffeine cache, by adding it and org.springframework.cache.caffeine.CaffeineCacheManager to the classpath.
2024-11-27T10:28:20.050+01:00 INFO 35724 --- [hello-application] [ restartedMain] o.s.c.n.eureka.InstanceInfoFactory : Setting initial instance status as: STARTING
2024-11-27T10:28:20.060+01:00 INFO 35724 --- [hello-application] [ restartedMain] com.netflix.discovery.DiscoveryClient : Initializing Eureka in region us-east-1
2024-11-27T10:28:20.062+01:00 INFO 35724 --- [hello-application] [ restartedMain] c.n.d.s.r.aws.ConfigClusterResolver : Resolving eureka endpoints via configuration
2024-11-27T10:28:20.062+01:00 DEBUG 35724 --- [hello-application] [ restartedMain] c.n.discovery.endpoint.EndpointUtils : The availability zone for the given region us-east-1 are [defaultZone]
2024-11-27T10:28:20.063+01:00 DEBUG 35724 --- [hello-application] [ restartedMain] c.n.d.s.r.aws.ConfigClusterResolver : Config resolved to [AwsEndpoint{ serviceUrl='http://localhost:8761/eureka/', region='us-east-1', zone='defaultZone'}]
2024-11-27T10:28:20.063+01:00 DEBUG 35724 --- [hello-application] [ restartedMain] c.n.d.s.r.a.ZoneAffinityClusterResolver : Local zone=defaultZone; resolved to: [AwsEndpoint{ serviceUrl='http://localhost:8761/eureka/', region='us-east-1', zone='defaultZone'}]
2024-11-27T10:28:20.066+01:00 INFO 35724 --- [hello-application] [ restartedMain] com.netflix.discovery.DiscoveryClient : Disable delta property : false
2024-11-27T10:28:20.066+01:00 INFO 35724 --- [hello-application] [ restartedMain] com.netflix.discovery.DiscoveryClient : Single vip registry refresh property : null
2024-11-27T10:28:20.066+01:00 INFO 35724 --- [hello-application] [ restartedMain] com.netflix.discovery.DiscoveryClient : Force full registry fetch : false
2024-11-27T10:28:20.066+01:00 INFO 35724 --- [hello-application] [ restartedMain] com.netflix.discovery.DiscoveryClient : Application is null : false
2024-11-27T10:28:20.066+01:00 INFO 35724 --- [hello-application] [ restartedMain] com.netflix.discovery.DiscoveryClient : Registered Applications size is zero : true
2024-11-27T10:28:20.066+01:00 INFO 35724 --- [hello-application] [ restartedMain] com.netflix.discovery.DiscoveryClient : Application version is -1: true
2024-11-27T10:28:20.066+01:00 INFO 35724 --- [hello-application] [ restartedMain] com.netflix.discovery.DiscoveryClient : Getting all instance registry info from the eureka server
2024-11-27T10:28:20.066+01:00 DEBUG 35724 --- [hello-application] [ restartedMain] c.n.d.s.t.d.SessionedEurekaHttpClient : Ending a session and starting anew
2024-11-27T10:28:20.155+01:00 ERROR 35724 --- [hello-application] [ restartedMain] scoveryClientServiceInstanceListSupplier : Exception occurred while retrieving instances for service localhost
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'scopedTarget.eurekaClient': Requested bean is currently in creation: Is there an unresolvable circular reference or an asynchronous initialization dependency?
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:265) ~[spring-beans-6.2.0.jar:6.2.0]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Assembly trace from producer [reactor.core.publisher.MonoCallable] :
reactor.core.publisher.Mono.fromCallable(Mono.java:524)
org.springframework.cloud.loadbalancer.core.DiscoveryClientServiceInstanceListSupplier.lambda$new$1(DiscoveryClientServiceInstanceListSupplier.java:64)
Error has been observed at the following site(s):
*__Mono.fromCallable ⇢ at org.springframework.cloud.loadbalancer.core.DiscoveryClientServiceInstanceListSupplier.lambda$new$1(DiscoveryClientServiceInstanceListSupplier.java:64)
*_________Flux.defer ⇢ at org.springframework.cloud.loadbalancer.core.DiscoveryClientServiceInstanceListSupplier.<init>(DiscoveryClientServiceInstanceListSupplier.java:64)
|_ Flux.timeout ⇢ at org.springframework.cloud.loadbalancer.core.DiscoveryClientServiceInstanceListSupplier.<init>(DiscoveryClientServiceInstanceListSupplier.java:65)
Original Stack Trace:
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:265) ~[spring-beans-6.2.0.jar:6.2.0]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-6.2.0.jar:6.2.0]
at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35) ~[spring-aop-6.2.0.jar:6.2.0]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:203) ~[spring-aop-6.2.0.jar:6.2.0]
at jdk.proxy3/jdk.proxy3.$Proxy74.getInstancesByVipAddress(Unknown Source) ~[na:na]
at org.springframework.cloud.netflix.eureka.EurekaDiscoveryClient.getInstances(EurekaDiscoveryClient.java:64) ~[spring-cloud-netflix-eureka-client-4.2.0-RC1.jar:4.2.0-RC1]
at org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClient.getInstances(CompositeDiscoveryClient.java:54) ~[spring-cloud-commons-4.2.0-RC1.jar:4.2.0-RC1]
at org.springframework.cloud.loadbalancer.core.DiscoveryClientServiceInstanceListSupplier.lambda$new$0(DiscoveryClientServiceInstanceListSupplier.java:64) ~[spring-cloud-loadbalancer-4.2.0-RC1.jar:4.2.0-RC1]
I have the following dependencies in my app:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
</dependencies>
Sample I'll add a reproducing example. cloud-teaser.zip
Comment From: OlgaMaciaszek
Hello @eiswind, thanks for creating the issue. Will take a look on Monday.
Comment From: OlgaMaciaszek
It's actually not a bug exactly, but a consequence of switching to RestClient.Builder
being the default implementation for creating Eureka connections (see https://github.com/spring-cloud/spring-cloud-netflix/issues/4257). Since the app will now be trying to find a RestClient.Builder/ RestClient
bean to communicate with Eureka as a first option, and the only available RestClient.Builder
is load-balanced, a load-balanced RestClient.Builder
will be used where a non load-balanced one is needed. As a workaround, either the config should be changed to have another, non-load-balanced RestClient.Builder
bean added as @Primary
and @LoadBalanced
use as a qualifier where needed to get the right bean, like so:
@SpringBootApplication
public class HelloApplication {
public static void main(String[] args) {
SpringApplication.run(HelloApplication.class, args);
}
@LoadBalanced // <1>
@Bean
RestClient.Builder lbRestClientBuilder() {
return RestClient.builder();
}
@Primary
@Bean
RestClient.Builder restClientBuilder() {
return RestClient.builder();
}
}
@Controller
public class HelloController {
@Autowired
@LoadBalanced
RestClient.Builder restClientBuilder;
@GetMapping("/")
String home(Model model) {
var response = restClientBuilder.build()
.get()
.uri(URI.create("http://HELLO-SERVICE/sayhello")) // <1>
.retrieve()
.body(String.class);
model.addAttribute("response", response);
return "hello";
}
}
or eureka.client.restclient.enabled
should be set to false
.
Comment From: OlgaMaciaszek
While this is not a bug, it's a possible backwards compatibility issue, so it might be worth considering making RestClient
-based implementation default in a major instead. For team discussion.
Comment From: OlgaMaciaszek
We've decided to revert the defaults and change things for the major. Also consider providing a more explicit way for the users to indicate a RestClient.Builder
to be used or otherwise create our own instance.
Comment From: eiswind
Tests are green with the release. Thanks for your support!