본문 바로가기

Various Error

[Eureka] Eureka Client의 UnsatisfiedDependencyException 에러

Eureka Server와 Eureka Client를 멀티 모듈로 연습해보는 과정에서 아래와 같은 에러가 발생하였음

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'scopedTarget.eurekaClient' defined in class path resource [org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration$RefreshableEurekaClientConfiguration.class]: Unsatisfied dependency expressed through method 'eurekaClient' parameter 3: No qualifying bean of type 'cohttp://m.netflix.discovery.shared.transport.jersey.TransportClientFactories' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:795) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:542) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1355) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1185) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$1(AbstractBeanFactory.java:376) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.cloud.context.scope.GenericScope$BeanLifecycleWrapper.getBean(GenericScope.java:375) ~[spring-cloud-context-4.1.4.jar:4.1.4]
at org.springframework.cloud.context.scope.GenericScope.get(GenericScope.java:179) ~[spring-cloud-context-4.1.4.jar:4.1.4]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:373) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35) ~[spring-aop-6.1.11.jar:6.1.11]
at org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration.getTargetObject(EurekaRegistration.java:128) ~[spring-cloud-netflix-eureka-client-4.1.3.jar:4.1.3]
at org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration.getEurekaClient(EurekaRegistration.java:116) ~[spring-cloud-netflix-eureka-client-4.1.3.jar:4.1.3]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:281) ~[spring-core-6.1.11.jar:6.1.11]
at org.springframework.cloud.context.scope.GenericScope$LockedScopedProxyFactoryBean.invoke(GenericScope.java:482) ~[spring-cloud-context-4.1.4.jar:4.1.4]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.11.jar:6.1.11]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.11.jar:6.1.11]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:720) ~[spring-aop-6.1.11.jar:6.1.11]
at org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration$$SpringCGLIB$$0.getEurekaClient() ~[spring-cloud-netflix-eureka-client-4.1.3.jar:4.1.3]
at org.springframework.cloud.netflix.eureka.serviceregistry.EurekaServiceRegistry.maybeInitializeClient(EurekaServiceRegistry.java:83) ~[spring-cloud-netflix-eureka-client-4.1.3.jar:4.1.3]
at org.springframework.cloud.netflix.eureka.serviceregistry.EurekaServiceRegistry.register(EurekaServiceRegistry.java:66) ~[spring-cloud-netflix-eureka-client-4.1.3.jar:4.1.3]
at org.springframework.cloud.netflix.eureka.serviceregistry.EurekaAutoServiceRegistration.start(EurekaAutoServiceRegistration.java:89) ~[spring-cloud-netflix-eureka-client-4.1.3.jar:4.1.3]
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:285) ~[spring-context-6.1.11.jar:6.1.11]
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:469) ~[spring-context-6.1.11.jar:6.1.11]
at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na]
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:257) ~[spring-context-6.1.11.jar:6.1.11]
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:202) ~[spring-context-6.1.11.jar:6.1.11]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:990) ~[spring-context-6.1.11.jar:6.1.11]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:628) ~[spring-context-6.1.11.jar:6.1.11]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-3.3.2.jar:3.3.2]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[spring-boot-3.3.2.jar:3.3.2]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:335) ~[spring-boot-3.3.2.jar:3.3.2]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) ~[spring-boot-3.3.2.jar:3.3.2]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352) ~[spring-boot-3.3.2.jar:3.3.2]
at io.spring.eurekaclient.EurekaClientApplication.main(EurekaClientApplication.java:12) ~[main/:na]
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'cohttp://m.netflix.discovery.shared.transport.jersey.TransportClientFactories' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1880) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1406) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1353) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:904) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:782) ~[spring-beans-6.1.11.jar:6.1.11]
... 39 common frames omitted

2024-08-20T20:22:58.680+09:00  WARN 7032 --- [api-gateway] [           main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'eurekaAutoServiceRegistration'
2024-08-20T20:22:58.687+09:00  INFO 7032 --- [api-gateway] [           main] .s.b.a.l.ConditionEvaluationReportLogger : 

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2024-08-20T20:22:58.706+09:00 ERROR 7032 --- [api-gateway] [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.context.ApplicationContextException: Failed to start bean 'eurekaAutoServiceRegistration'
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:288) ~[spring-context-6.1.11.jar:6.1.11]
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:469) ~[spring-context-6.1.11.jar:6.1.11]
at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na]
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:257) ~[spring-context-6.1.11.jar:6.1.11]
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:202) ~[spring-context-6.1.11.jar:6.1.11]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:990) ~[spring-context-6.1.11.jar:6.1.11]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:628) ~[spring-context-6.1.11.jar:6.1.11]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-3.3.2.jar:3.3.2]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[spring-boot-3.3.2.jar:3.3.2]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:335) ~[spring-boot-3.3.2.jar:3.3.2]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) ~[spring-boot-3.3.2.jar:3.3.2]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352) ~[spring-boot-3.3.2.jar:3.3.2]
at io.spring.eurekaclient.EurekaClientApplication.main(EurekaClientApplication.java:12) ~[main/:na]
Caused by: java.lang.NullPointerException: Cannot invoke "org.springframework.cloud.netflix.eureka.CloudEurekaClient.getApplications()" because the return value of "org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration.getEurekaClient()" is null
at org.springframework.cloud.netflix.eureka.serviceregistry.EurekaServiceRegistry.maybeInitializeClient(EurekaServiceRegistry.java:83) ~[spring-cloud-netflix-eureka-client-4.1.3.jar:4.1.3]
at org.springframework.cloud.netflix.eureka.serviceregistry.EurekaServiceRegistry.register(EurekaServiceRegistry.java:66) ~[spring-cloud-netflix-eureka-client-4.1.3.jar:4.1.3]
at org.springframework.cloud.netflix.eureka.serviceregistry.EurekaAutoServiceRegistration.start(EurekaAutoServiceRegistration.java:89) ~[spring-cloud-netflix-eureka-client-4.1.3.jar:4.1.3]
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:285) ~[spring-context-6.1.11.jar:6.1.11]
... 12 common frames omitted

 

가장 처음 블로그를 보면서 테스트를 성공한 뒤, 블로그에 내용을 작성하기 위해 다시 시도 하는데 application.yml과 어노테이션을 똑같이 사용했던 것 같음에도 불구하고 계속 위와 같은 에러가 발생함

 

1. application.yml이 원인?

  • 블로그를 따라 시도했던 것과 다르게 application.yml에서 eureka.client.server-url.defaultZone과 spring.application.name을 마음대로 지정할 수 있을 거라 생각했기 때문에 yml에 원인 있다고 생각했음

⇒ 따라한 블로그와 완전히 동일하게 하였지만 실패

 

2. ChatGPT에 의하면 버전이 맞지 않거나 아래 설정을 추가하면 해결이 될 것 같다고 함

eureka:
  client:
    transport:
      strategy: jersey

 

  실패

⇒  이후 구글링, 새 프로젝트 다양한 방법으로 모두 시도 하였지만 실패

3. Spring Web 의존성 추가

Eureka Client측에 Spring Web 의존성을 추가하였더니 성공,,,!!

implementation 'org.springframework.boot:spring-boot-starter-web'

 

 

왜 이런 문제가 발생하였는가?

  • 참조하던 멀티 모듈의 블로그 내용
루트 프로젝트의 build.gradle에서 하위 모듈의 gradle 세팅을 모두 할 수 도 있고 각 모듈의 build.gradle 세팅을 따로 해주어도 된다.

 

  • 위 내용을 루트 프로젝트의 build.gradle에 설정하면 모든 모듈에 공통적으로 dependency가 추가가 된다는 의미로 해석을 했고 다음과 같이 설정
eureka-example(루트 프로젝트) 의존성 : Spring Web, Lombok
eureka-server 의존성 : Eureka Server
eureka-client 의존성 : Eureka Discovery Client

 

  • 루트 프로젝트의 의존성이 하위 모듈에게 모두 적용이 된다면?
    • 아래처럼 의존성이 추가될 것이라고 예상하였음

eureka-server : Eureka Server, Spring Web, Lombok

eureka-client : Eureka Discovery Client, Spring Web, Lombok

 

  • 하지만 Spring Web을 eureka-client에 추가를 해주니 에러가 사라졌다는 것은 루트 프로젝트의 build.gradle과 하위 모듈은 관련이 없다는 것
  • 이것을 깨닫고 나서 다시 보니, 루트 프로젝트의 build.gradle에서 하위 모듈에 적용시키려면 아래의 코드처럼 작성할 경우 일일히 하위 모듈 build.gradle을 찾아가지 않고, 루트 프로젝트에서 한 번에 컨트롤을 할 수 있다는 의미로 다시 보임

 

  • 그렇다면, 왜 Eureka Server는 Spring Web이 없이도 잘 되고, Eureka Client는 Spring Web이 있어야만 할까?
  • 나의 지식으로는 해결할 수 없는 문제 같아 ChatGPT 내용을 가지고 왔다

 


오류 해결 후기

Spring Web을 추가하는 건 너무 당연한 것이라 그런가?

오류를 긁어서 던져줬을 때 ChatGPT도 아래 같은 이야기를 하면서 Spring Web에 전혀 접근하지 못했고, 구글링에도 전혀 나오지 않아서 멘탈이 나갈 뻔 했다,,,

이 에러는 Spring Cloud Netflix Eureka를 사용하는 중 TransportClientFactories 빈이 없어서 발생한 문제입니다. 구체적으로, EurekaClientAutoConfiguration에서 TransportClientFactories 빈이 필요한데 이를 찾지 못하고 있습니다. 이 오류는 주로 다음과 같은 이유로 발생합니다:

Spring Cloud Netflix Eureka와의 버전 불일치: Spring Boot, Spring Cloud, 그리고 Netflix Eureka의 버전이 맞지 않아서 생길 수 있습니다.클라이언트 전송 방식 설정 문제: jersey 기반의 TransportClientFactories 빈이 생성되지 않는 경우입니다.

해결 방법:
버전 호환성 확인: Spring Boot와 Spring Cloud의 버전이 호환되는지 확인하세요. 예를 들어, Spring Boot 3.x를 사용할 경우 Spring Cloud 2023.x 버전이 호환됩니다.

Spring Cloud Netflix Eureka 종속성 추가: spring-cloud-starter-netflix-eureka-client 의존성을 다시 확인하거나, 필요한 경우 spring-cloud-starter-netflix-eureka-server도 추가하세요.

Jersey 전송 방식 설정: application.yml이나 application.properties에서 eureka.client.transport.strategy를 jersey로 설정하세요.

 

멀티 모듈 참조 블로그

https://velog.io/@haerong22/IntelliJ-%EB%A9%80%ED%8B%B0-%EB%AA%A8%EB%93%88-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EB%A7%8C%EB%93%A4%EA%B8%B0

 

[IntelliJ] 멀티 모듈 프로젝트 만들기

멀티 모듈 프로젝트 만들기

velog.io