The incompatibility was discovered in the following versions:
<dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-starter-server</artifactId> </dependency> <dependency> <groupId>io.pivotal.spring.cloud</groupId> <artifactId>spring-cloud-services-starter-service-registry</artifactId> </dependency>
This results in an application failing to start when deployed to Cloud Foundry. The initial error is more generic and advises the operator to enable bean overriding which can be achieved with the following configuration in the application.properties file:
spring.main.allow-bean-definition-overriding=true
After this change, the error provides the following details:
2022-04-19T18:21:27.15+0100 [APP/PROC/WEB/0] OUT Field optionalArgs in org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration required a single bean, but 2 were found: 2022-04-19T18:21:27.15+0100 [APP/PROC/WEB/0] OUT - restTemplateDiscoveryClientOptionalArgs: defined by method 'restTemplateDiscoveryClientOptionalArgs' in class path resource [org/springframework/cloud/netflix/eureka/config/DiscoveryClientOptionalArgsConfiguration.class] 2022-04-19T18:21:27.15+0100 [APP/PROC/WEB/0] OUT - discoveryClientOptionalArgs: defined by method 'discoveryClientOptionalArgs' in class path resource [io/pivotal/spring/cloud/service/registry/EurekaClientOAuth2AutoConfiguration.class]
Please note that when running the app in a local environment, the run succeeds and the application can register with Eureka. The issue only occurs in a Cloud Foundry deployment.
The issue occurs due to the spring-boot-admin-starter-server dependency defining another bean of AbstractDiscoveryClientOptionalArgs and Spring is failing to choose one or the other, which results the bean duplication error. To workaround this issue it is advised to use spring-cloud-starter-netflix-eureka-client dependency instead of spring-cloud-services-starter-service-registry:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
When using spring-cloud-services-starter-service-registry, the applications can be bound to the service instance using cf bind-service. However, this is not the case with Netflix's dependency. Netflix eureka does not know how to handle VCAP_SERVICE binding. As a result, even if the app was bound to the SCS service registry, it would still fail with "com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server" error because it is resolving Eureka server endpoints via configuration and tries to communicate through http://localhost:8761/eureka/
To work around this, additional configuration is required to assist the application to locate the service registry and point towards it. This can be done by setting eureka.client.service-url.defaultZone variable inside the application.properties or application.yml as advised by the official Spring documentation (please note that the /eureka/ ending is not needed when using SCS service registry). The service registry's URL can be found by running cf service <SERVICE_INSTANCE> .
Configuration examples:
application.properties
eureka.client.service-url.defaultZone=https://service-registry.example.url.com
application.yml
eureka: client: serviceUrl: defaultZone: https://service-registry.example.url.com
This configuration may lead to errors such as An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response and unable to find valid certification path to requested target . This is due to the fact that the access to the service registry is not provided through the service binding. The article describes how to tell application containers running Java apps to trust self-signed certs or a private or internal Certificate Authority (CA).
This issue has been fixed in the Spring Cloud Services Starters versions 3.3.1+ and above, as well as 3.4.1 and above.