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로 설정하세요.
멀티 모듈 참조 블로그
'Various Error' 카테고리의 다른 글
[Spring Cloud/API Gateway] Spring Reactive Web (0) | 2024.08.27 |
---|---|
[IntelliJ / FeignClient] 의존성 추가 후 어노테이션 인식 불가 (0) | 2024.08.22 |
[JSON] HttpMediaTypeNotAcceptableException (0) | 2024.08.19 |
[JSON] InvalidDefinitionException (0) | 2024.08.19 |
[Spring Data JPA] PropertyReferenceException 에러 (0) | 2024.08.16 |