Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplest @EnableEurekaClient app throws exception with eureka.client.enabled=false #1511

Closed
strelok1 opened this issue Nov 28, 2016 · 4 comments
Labels
Milestone

Comments

@strelok1
Copy link
Contributor

With Camden.SR2 if @EnableEurekaClient is on, but eureka.client.enabled=false, which is a totally valid use case (for example in a local dev profile when you don't want to connect to Eureka Server), this simple app throws an exception. This used to work in Brixton.

I believe this commit to remove the usage of deprecated constructor is the culprit: 856c471

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableEurekaClient
public class DemoSpringCloudEurekaBugApplication {

	public class ClassThatUsesLoadbalancer {

		private LoadBalancerClient loadBalancerClient;

		public ClassThatUsesLoadbalancer(LoadBalancerClient loadBalancerClient) {
			this.loadBalancerClient = loadBalancerClient;
		}

		public void doStuff() {
			ServiceInstance serviceInstance = loadBalancerClient.choose("http://host/doStuff");
			if (serviceInstance!=null) {
				System.out.println("cool, there is a service instance, because Eureka discovery is enabled and the service is registered");
			} else {
				System.out.println("Oh no instance, because Eureka is disabled or there is no service matching. But this is ok");
			}
		}
	}

	public static void main(String[] args) {
		ConfigurableApplicationContext applicationContext = SpringApplication.run(DemoSpringCloudEurekaBugApplication.class, args);
		ClassThatUsesLoadbalancer classThatUsesLoadbalancer = applicationContext.getBean(ClassThatUsesLoadbalancer.class);
		classThatUsesLoadbalancer.doStuff();
	}

	@Bean
	ClassThatUsesLoadbalancer classThatUsesLoadbalancer(LoadBalancerClient loadBalancerClient){
		return new ClassThatUsesLoadbalancer(loadBalancerClient);
	}
}

The exception:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'ribbonLoadBalancingHttpClient' defined in org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration$HttpClientRibbonConfiguration: Unsatisfied dependency expressed through method 'ribbonLoadBalancingHttpClient' parameter 2; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ribbonLoadBalancer' defined in org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.netflix.loadbalancer.ILoadBalancer]: Factory method 'ribbonLoadBalancer' threw exception; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.netflix.discovery.EurekaClient' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:467)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1128)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1022)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:512)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:754)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
	at org.springframework.cloud.context.named.NamedContextFactory.createContext(NamedContextFactory.java:110)
	at org.springframework.cloud.context.named.NamedContextFactory.getContext(NamedContextFactory.java:79)
	at org.springframework.cloud.context.named.NamedContextFactory.getInstance(NamedContextFactory.java:115)
	at org.springframework.cloud.netflix.ribbon.SpringClientFactory.getInstance(SpringClientFactory.java:111)
	at org.springframework.cloud.netflix.ribbon.SpringClientFactory.getLoadBalancer(SpringClientFactory.java:57)
	at org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.getLoadBalancer(RibbonLoadBalancerClient.java:141)
	at org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.getServer(RibbonLoadBalancerClient.java:130)
	at org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.choose(RibbonLoadBalancerClient.java:62)
	at com.example.DemoSpringCloudEurekaBugApplication$ClassThatUsesLoadbalancer.doStuff(DemoSpringCloudEurekaBugApplication.java:24)
@strelok1
Copy link
Contributor Author

After a bit of debugging and looking through the available properties on EurekaClientConfigBean
Looks like the only way to get the same behaviour as before is to remove eureka.client.enabled=false
and instead specify:

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false

This way the instance of a CloudEurekaClient is created and the LoadBalancerClient behaves the same way but does not connect to registry.

I still think it should not throw that exception when eureka.client.enabled=false.

spencergibb added a commit that referenced this issue Nov 29, 2016
Specifically, add `@ConditionalOnBean(EurekaClient.class)`.

Fixes an issue where eureka and ribbon are on the classpath, eureka.client.enabled=false which would cause a bean not found exception.

fixes gh-1511
@spencergibb
Copy link
Member

Camden fix here d1f8c03

@spencergibb spencergibb added this to the 1.2.4.RELEASE milestone Nov 29, 2016
@arindac
Copy link

arindac commented Aug 22, 2018

I was getting below exception:

org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration': Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)

Then in application.properties file I added below mentioned property and it worked for me. Thanks @strelok1 for the hint.
eureka.client.enabled=false

@spencergibb
Copy link
Member

@arindac please don't comment on closed issues. This fixed the use of the property you mentioned, it wasn't a hint.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants