[Bug] BeanDefinitionOverrideException when using spring-modulith-events-amqp with Eureka Client
How I Found This
I was implementing the Outbox Pattern in an MSA environment and added spring-modulith-events-amqp as a dependency.
After that, I added spring-cloud-netflix-eureka-client for service discovery, and the application failed to start with the error below.
Environment
- Spring Boot: 4.1.0
- Spring Modulith: 2.1.0
- Spring Cloud: 2025.1.2 (including Eureka Client)
Error Message
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'rabbitTemplateCustomizer', defined in class path resource
[org/springframework/modulith/events/amqp/RabbitJacksonConfiguration.class],
could not be registered. A bean with that name has already been defined in class path resource
[org/springframework/modulith/events/amqp/RabbitJackson2Configuration.class]
and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting
spring.main.allow-bean-definition-overriding=true
Root Cause Analysis
spring-modulith-events-amqp contains two configuration classes:
| Class |
Based on |
Activation Condition |
Status |
RabbitJacksonConfiguration |
Jackson 3.x (JsonMapper) |
@ConditionalOnClass(JsonMapper.class) |
Current |
RabbitJackson2Configuration |
Jackson 2.x (ObjectMapper) |
@ConditionalOnClass(ObjectMapper.class) |
@Deprecated |
Before adding Eureka Client:
- Only
JsonMapper (Jackson 3.x) exists on the classpath
- Only
RabbitJacksonConfiguration is activated → no conflict
RabbitJackson2Configuration is inactive because ObjectMapper is not present
After adding Eureka Client:
- Eureka Client brings
com.fasterxml.jackson (Jackson 2.x) onto the classpath
ObjectMapper now exists, satisfying RabbitJackson2Configuration's activation condition
- Both classes attempt to register a bean named
rabbitTemplateCustomizer → conflict!
Root Cause
Both classes attempt to register a bean with the same name (rabbitTemplateCustomizer) without being aware of each other.
While RabbitJacksonConfiguration (current) is declared before RabbitJackson2Configuration in AutoConfiguration.imports, this ordering is not officially guaranteed by Spring.
Two fixes are needed:
- Add
before to RabbitJacksonConfiguration → guarantee the current version is always registered first
- Add
@ConditionalOnMissingBean to RabbitJackson2Configuration → skip registration if the bean already exists
// RabbitJacksonConfiguration (current) — add before
@AutoConfiguration(before = RabbitJackson2Configuration.class) // needs to be added
@ConditionalOnClass({ RabbitTemplate.class, JsonMapper.class })
class RabbitJacksonConfiguration {
@Bean
@ConditionalOnBean(JsonMapper.class)
RabbitTemplateCustomizer rabbitTemplateCustomizer(JsonMapper mapper) { ... }
}
// RabbitJackson2Configuration (deprecated) — add @ConditionalOnMissingBean
@Deprecated
@AutoConfiguration
@ConditionalOnClass({ RabbitTemplate.class, ObjectMapper.class })
class RabbitJackson2Configuration {
@Deprecated
@Bean
@ConditionalOnBean(ObjectMapper.class)
@ConditionalOnMissingBean(name = "rabbitTemplateCustomizer") // needs to be added
RabbitTemplateCustomizer rabbitTemplateCustomizer(ObjectMapper mapper) { ... }
}
Workaround
Add the following to application.yml to exclude RabbitJackson2Configuration:
spring:
autoconfigure:
exclude:
- org.springframework.modulith.events.amqp.RabbitJackson2Configuration
Korean (원본)
[버그] spring-modulith-events-amqp와 Eureka Client 함께 사용 시 BeanDefinitionOverrideException 발생
발견 경위
MSA 환경에서 아웃박스 패턴(Outbox Pattern)을 구현하기 위해 spring-modulith-events-amqp 의존성을 추가했습니다.
이후 서비스 디스커버리를 위해 spring-cloud-netflix-eureka-client를 추가했더니 애플리케이션 기동 시 아래와 같은 오류가 발생했습니다.
환경
- Spring Boot: 4.1.0
- Spring Modulith: 2.1.0
- Spring Cloud: 2025.1.2 (Eureka Client 포함)
오류 메시지
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'rabbitTemplateCustomizer', defined in class path resource
[org/springframework/modulith/events/amqp/RabbitJacksonConfiguration.class],
could not be registered. A bean with that name has already been defined in class path resource
[org/springframework/modulith/events/amqp/RabbitJackson2Configuration.class]
and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting
spring.main.allow-bean-definition-overriding=true
원인 분석
spring-modulith-events-amqp 내부에는 두 개의 설정 클래스가 존재합니다.
| 클래스 |
기반 |
활성화 조건 |
상태 |
RabbitJacksonConfiguration |
Jackson 3.x (JsonMapper) |
@ConditionalOnClass(JsonMapper.class) |
최신 |
RabbitJackson2Configuration |
Jackson 2.x (ObjectMapper) |
@ConditionalOnClass(ObjectMapper.class) |
@Deprecated |
Eureka Client 추가 전:
- classpath에
JsonMapper(Jackson 3.x)만 존재
RabbitJacksonConfiguration만 활성화 → 충돌 없음
RabbitJackson2Configuration은 ObjectMapper가 없으므로 비활성화
Eureka Client 추가 후:
- Eureka Client가
com.fasterxml.jackson(Jackson 2.x)을 classpath에 추가
ObjectMapper가 생기면서 RabbitJackson2Configuration 활성화 조건 충족
- 두 설정 클래스가 동시에
rabbitTemplateCustomizer라는 같은 이름의 빈 등록 시도 → 충돌!
근본 원인
두 클래스가 서로를 인식하지 못하고 동시에 같은 이름의 빈(rabbitTemplateCustomizer) 등록을 시도합니다.
AutoConfiguration.imports 파일 순서상 RabbitJacksonConfiguration(신버전)이 먼저 선언되어 있어 일반적으로는 신버전이 먼저 등록되지만, 이 순서는 Spring이 공식적으로 보장하지 않습니다.
따라서 두 가지 수정이 모두 필요합니다:
RabbitJacksonConfiguration에 before 추가 → 항상 신버전이 먼저 등록되도록 순서 보장
RabbitJackson2Configuration에 @ConditionalOnMissingBean 추가 → 이미 빈이 있으면 등록하지 않도록
// RabbitJacksonConfiguration (신버전) — before 추가
@AutoConfiguration(before = RabbitJackson2Configuration.class) // 추가 필요
@ConditionalOnClass({ RabbitTemplate.class, JsonMapper.class })
class RabbitJacksonConfiguration {
@Bean
@ConditionalOnBean(JsonMapper.class)
RabbitTemplateCustomizer rabbitTemplateCustomizer(JsonMapper mapper) { ... }
}
// RabbitJackson2Configuration (구버전) — @ConditionalOnMissingBean 추가
@Deprecated
@AutoConfiguration
@ConditionalOnClass({ RabbitTemplate.class, ObjectMapper.class })
class RabbitJackson2Configuration {
@Deprecated
@Bean
@ConditionalOnBean(ObjectMapper.class)
@ConditionalOnMissingBean(name = "rabbitTemplateCustomizer") // 추가 필요
RabbitTemplateCustomizer rabbitTemplateCustomizer(ObjectMapper mapper) { ... }
}
임시 해결 방법
application.yml에 아래 설정을 추가하여 RabbitJackson2Configuration을 제외합니다.
spring:
autoconfigure:
exclude:
- org.springframework.modulith.events.amqp.RabbitJackson2Configuration
[Bug] BeanDefinitionOverrideException when using spring-modulith-events-amqp with Eureka Client
How I Found This
I was implementing the Outbox Pattern in an MSA environment and added
spring-modulith-events-amqpas a dependency.After that, I added
spring-cloud-netflix-eureka-clientfor service discovery, and the application failed to start with the error below.Environment
Error Message
Root Cause Analysis
spring-modulith-events-amqpcontains two configuration classes:RabbitJacksonConfigurationJsonMapper)@ConditionalOnClass(JsonMapper.class)RabbitJackson2ConfigurationObjectMapper)@ConditionalOnClass(ObjectMapper.class)@DeprecatedBefore adding Eureka Client:
JsonMapper(Jackson 3.x) exists on the classpathRabbitJacksonConfigurationis activated → no conflictRabbitJackson2Configurationis inactive becauseObjectMapperis not presentAfter adding Eureka Client:
com.fasterxml.jackson(Jackson 2.x) onto the classpathObjectMappernow exists, satisfyingRabbitJackson2Configuration's activation conditionrabbitTemplateCustomizer→ conflict!Root Cause
Both classes attempt to register a bean with the same name (
rabbitTemplateCustomizer) without being aware of each other.While
RabbitJacksonConfiguration(current) is declared beforeRabbitJackson2ConfigurationinAutoConfiguration.imports, this ordering is not officially guaranteed by Spring.Two fixes are needed:
beforetoRabbitJacksonConfiguration→ guarantee the current version is always registered first@ConditionalOnMissingBeantoRabbitJackson2Configuration→ skip registration if the bean already existsWorkaround
Add the following to
application.ymlto excludeRabbitJackson2Configuration:Korean (원본)
[버그] spring-modulith-events-amqp와 Eureka Client 함께 사용 시 BeanDefinitionOverrideException 발생
발견 경위
MSA 환경에서 아웃박스 패턴(Outbox Pattern)을 구현하기 위해
spring-modulith-events-amqp의존성을 추가했습니다.이후 서비스 디스커버리를 위해
spring-cloud-netflix-eureka-client를 추가했더니 애플리케이션 기동 시 아래와 같은 오류가 발생했습니다.환경
오류 메시지
원인 분석
spring-modulith-events-amqp내부에는 두 개의 설정 클래스가 존재합니다.RabbitJacksonConfigurationJsonMapper)@ConditionalOnClass(JsonMapper.class)RabbitJackson2ConfigurationObjectMapper)@ConditionalOnClass(ObjectMapper.class)@DeprecatedEureka Client 추가 전:
JsonMapper(Jackson 3.x)만 존재RabbitJacksonConfiguration만 활성화 → 충돌 없음RabbitJackson2Configuration은ObjectMapper가 없으므로 비활성화Eureka Client 추가 후:
com.fasterxml.jackson(Jackson 2.x)을 classpath에 추가ObjectMapper가 생기면서RabbitJackson2Configuration활성화 조건 충족rabbitTemplateCustomizer라는 같은 이름의 빈 등록 시도 → 충돌!근본 원인
두 클래스가 서로를 인식하지 못하고 동시에 같은 이름의 빈(
rabbitTemplateCustomizer) 등록을 시도합니다.AutoConfiguration.imports파일 순서상RabbitJacksonConfiguration(신버전)이 먼저 선언되어 있어 일반적으로는 신버전이 먼저 등록되지만, 이 순서는 Spring이 공식적으로 보장하지 않습니다.따라서 두 가지 수정이 모두 필요합니다:
RabbitJacksonConfiguration에before추가 → 항상 신버전이 먼저 등록되도록 순서 보장RabbitJackson2Configuration에@ConditionalOnMissingBean추가 → 이미 빈이 있으면 등록하지 않도록임시 해결 방법
application.yml에 아래 설정을 추가하여RabbitJackson2Configuration을 제외합니다.