
Kafka 메시지를 Consumer에서 처리하는 과정에서 아래와 같은 ClassNotFoundException이 발생했다.
Caused by: java.lang.ClassNotFoundException: finpago.matchingservice.matching.messaging.events.TradeMatchingEvent
이는 Execution Service에서 Kafka 메시지를 역직렬화할 때 TradeMatchingEvent 클래스를 찾을 수 없어 발생하는 문제다.
원래 각 모듈마다 TradeMatchingEvent을 넣어서 사용햇는데 (객체 내용으로 판별하는줄)
그 파일 경로로 판단하는거여서 경로가 달라서 역직렬화 오류가 생기는거엿다
현재 Matching Service가 TradeMatchingEvent를 Kafka에 전송하고 있지만, Execution Service에서는 해당 클래스를 찾을 수 없다.
이는 TradeMatchingEvent가 Matching Service의 패키지 경로에 존재하기 때문이며, Execution Service에서는 이를 로드할 수 없는 상태이다.
Caused by: java.lang.ClassNotFoundException: finpago.matchingservice.matching.messaging.events.TradeMatchingEvent
Execution Service가 Matching Service에서 전송한 TradeMatchingEvent를 역직렬화하려고 하지만, 해당 클래스가 존재하지 않아 역직렬화에 실패한다.
TradeMatchingEvent 클래스를 사용하도록 설정현재 Matching 모듈과 Execution 모듈이 서로 다른 패키지에서 TradeMatchingEvent를 정의하고 있기 때문에, Kafka 메시지를 처리할 때 클래스가 일치하지 않아 역직렬화 오류가 발생한다.
해결책: 공통 모듈에 TradeMatchingEvent와 OrderCreateReqEvent을 생성하여 공유
TradeMatchingEvent, OrderCreateReqEvent 클래스를 common 모듈로 이동한다.
finpago.common.messaging.events.TradeMatchingEventMatchingService 및 ExecutionService가 공통 모듈을 의존하도록 설정
build.gradle에 다음과 같이 추가한다.dependencies {
implementation project(':common')
}
Kafka Consumer 및 Producer 설정에서 올바른 패키지 경로를 지정
@Bean
public ConsumerFactory<String, TradeMatchingEvent> tradeConsumerFactory() {
Map<String, Object> props = new HashMap<>();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, BOOTSTRAP_SERVERS);
props.put(ConsumerConfig.GROUP_ID_CONFIG, GROUP_ID);
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
// 공통 모듈의 패키지로 변경
props.put(JsonDeserializer.VALUE_DEFAULT_TYPE, "finpago.common.messaging.events.TradeMatchingEvent");
props.put(JsonDeserializer.TRUSTED_PACKAGES, "finpago.common.messaging.events");
return new DefaultKafkaConsumerFactory<>(props);
}
@Bean
public ProducerFactory<String, TradeMatchingEvent> tradeProducerFactory() {
Map<String, Object> props = new HashMap<>();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, BOOTSTRAP_SERVERS);
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
// 헤더 정보를 추가하여 직렬화 문제 방지
props.put(JsonSerializer.ADD_TYPE_INFO_HEADERS, true);
return new DefaultKafkaProducerFactory<>(props);
}
TRUSTED_PACKAGES 설정공통 모듈을 사용하더라도 Kafka Consumer가 특정 패키지만 신뢰하도록 설정하면 역직렬화 오류가 발생할 수 있다.
이를 방지하기 위해 TRUSTED_PACKAGES 설정을 수정해야 한다.
@Bean
public ConsumerFactory<String, TradeMatchingEvent> tradeConsumerFactory() {
Map<String, Object> props = new HashMap<>();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, BOOTSTRAP_SERVERS);
props.put(ConsumerConfig.GROUP_ID_CONFIG, GROUP_ID);
props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
// Matching 모듈에서 보낸 메시지를 신뢰할 수 있도록 설정
props.put(JsonDeserializer.TRUSTED_PACKAGES, "finpago.common.messaging.events");
return new DefaultKafkaConsumerFactory<>(props);
}
Kafka 메시지 역직렬화 오류(ClassNotFoundException)는 MatchingService와 ExecutionService가 서로 다른 패키지에 동일한 클래스를 정의할 때 발생할 수 있다.
이를 해결하려면 공통 모듈(common)을 만들어 모든 서비스에서 동일한 이벤트 클래스를 사용하도록 구성해야 한다.