인프런 커뮤니티 질문&답변
Spring Batch 4.3.10 ExecutionContext 한글 인코딩 이슈 관련 문의
작성
·
54
·
수정됨
1
안녕하세요, 강사님.
강의와 직접적인 내용은 아니지만, 사내에서 발생한 Spring Batch 오류와 관련해 조언을 구하고자 문의드립니다.
혹시 시간이 괜찮으시다면 의견을 주시면 정말 감사하겠습니다.
1. 사용 환경
Java 1.8
Spring Boot 2.7.18
Spring Batch 4.3.10
2. 문제 상황
Spring Batch의 ExecutionContext에 한글 문자열을 저장한 이후,
다음 배치 실행 시 아래와 같은 오류가 발생하며 Job이 지속적으로 실패하는 현상이 있었습니다.
java.lang.IllegalArgumentException: Unable to deserialize the execution context
at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao$ExecutionContextRowMapper.mapRow
~
Caused by: com.fasterxml.jackson.core.JsonParseException: Invalid UTF-8 start byte 0xb2
해당 Job은 chunk 기반 배치이며, 마지막 close() 시점에
다음 Step에서 사용할 정보를 ExecutionContext에 저장하고 있었습니다.
이때 ResultMsg: "정상 처리" 와 같이 한글 문자열을 저장한 이후부터 문제가 발생했습니다.
3. 원인 분석
IDE(Eclipse) 인코딩: UTF-8
DB 인코딩:
NLS_CHARACTERSET = KO16MSWIN949
BATCH_JOB_EXECUTION_CONTEXT 테이블에 데이터가 저장되는 구조로 확인했습니다.
SHORT_CONTEXT(VARCHAR2(2500))SERIALIZED_CONTEXT(CLOB)
2500byte 이하의 데이터는 SHORT_CONTEXT에 저장되는데,
해당 컬럼이 MS949 기반 VARCHAR2이다 보니
UTF-8 기반으로 직렬화된 ExecutionContext 내 한글 데이터가 깨지면서
다음 실행 시 역직렬화 실패가 발생한 것으로 판단했습니다.
4. 고민 중인 해결 방안
현재 아래와 같은 방안들을 검토 중입니다.
ExecutionContext에 한글 자체를 사용하지 않도록 제한
로깅/메시지 성 데이터는 저장하지 않거나, 필요 시 영문만 사용
ExecutionContext에 putString 시 인코딩 설정
ExecutionContext 직렬화 방식 변경
ExecutionContextSerializer를 DefaultExecutionContextSerializer 명시정으로 설정(Spring Batch 4는 기본적으로 JacksonExecutionContextStringSerializer)
5. 질문
강사님께서 보시기에 위 상황에서 가장 권장되는 해결 방향 또는 실무적으로 안전한 접근 방식은 무엇이라고 생각하시는지 궁금합니다.
긴 글 읽어주셔서 감사드리며, 가능하실 때 조언 주시면 많은 도움이 될 것 같습니다.
감사합니다.
답변 2
1
반갑다 덕덕형 💀
=====================================================================
:: EMERGENCY RESPONSE :: ENCODING MALFUNCTION DETECTED
=====================================================================
보고서 ID: INF-BATCH-ENC-001
발신: KILL-9
수신: 덕덕
분류: ExecutionContext UTF-8/MS949 충돌
=====================================================================
[ 상황 분석 ]
한글로 저장하면 저런 문제가 있었군. 나도 처음본 이슈이다 💀
=====================================================================
[ 전술적 대응 방안 분석 ]
먼저 핵심 질문 하나.
"ExecutionContext에 한글을 반드시 저장해야 하는가?"
---
[시나리오 1: 한글 저장이 필수가 아닌 경우]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
권장 전술: 한글 사용 제거
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
가장 간단하고 안전한 방법이다.
질의자가 제시한 예시:
ResultMsg: "정상 처리"
이것은 로깅/메시지성 데이터로 보인다.
ExecutionContext의 주 목적은 "재시작을 위한 상태 저장"이다.
로깅 메시지나 상태값을 여기 넣을 이유가 있을까?
대안
1. BatchStatus / ExitStatus 활용
- Spring Batch가 제공하는 표준 상태 체계
2. 필요시 영문 메시지로 대체
- "NORMAL_PROCESSING", "SUCCESS", "COMPLETED" 등
장점:
✅ 인코딩 이슈 원천 차단
✅ 시스템 복잡도 증가 없음
✅ 추가 설정 불필요
---
[시나리오 2: 한글 저장이 필수인 경우]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
권장 전술: DefaultExecutionContextSerializer로 변경
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
=====================================================================
[END OF TRANSMISSION]
[CLEARANCE: RESTRICTED]
=====================================================================0
안녕하세요, 인프런 AI 인턴입니다.
덕덕님, Spring Batch에서 한글 인코딩 문제로 인해 어려움을 겪고 계시는군요. 이 문제는 일반적으로 데이터베이스와 애플리케이션 간의 인코딩 불일치에서 발생할 수 있는 문제로 보입니다. 특히, ExecutionContext에 한글을 저장할 때, 인코딩에 주의해야 합니다.
원인 분석 및 해결 방안
인코딩 불일치 문제 확인:
- 우선, 애플리케이션이 사용하는 모든 부분의 인코딩 설정을 확인해 보세요. IDE, 데이터베이스, 애플리케이션(java source flags 포함)까지 모두 UTF-8로 통일되어 있는지 점검합니다.
- 우선, 애플리케이션이 사용하는 모든 부분의 인코딩 설정을 확인해 보세요. IDE, 데이터베이스, 애플리케이션(java source flags 포함)까지 모두 UTF-8로 통일되어 있는지 점검합니다.
한글 사용 제한:
- 말씀하신 첫 번째 방안처럼
ExecutionContext에서 한글 사용을 가급적 피하는 것이 가장 안전한 방법입니다. 이 방법은 인코딩 문제를 근본적으로 회피하는 방법이 됩니다.
- 중요한 저장 데이터는 영문이나 코드화된 형태로 저장하고, 필수적일 때만 한글을 사용하도록 하는 것이 좋습니다.
- 말씀하신 첫 번째 방안처럼
직렬화 방식 변경:
ExecutionContextSerializer를Jackson2ExecutionContextStringSerializer로 변경하는 방법은 직렬화된 데이터의 인코딩을 명시적으로 제어하기 때문에 유용할 수 있습니다. 이 방법은ExecutionContext의 직렬화 과정에서 인코딩 문제를 해결해 줄 수 있습니다.
- 하지만, 이 경우에도 데이터베이스 자체의 문자셋으로 인한 제한은 해결하기 어려울 수 있습니다. 따라서 데이터 전송 시 변환이 필요합니다.
데이터베이스 설정 변경:
- 데이터베이스의
NLS_CHARACTERSET을 UTF-8로 변경할 수 있다면, 가장 확실한 해결책이 될 수 있습니다. 다만, 이는 전체적인 데이터베이스 설계에 영향을 주므로 신중히 고려해야 합니다.
- 특히, 기존 데이터에 영향이 발생할 수 있으므로, 데이터베이스 관리자와 협의가 필요합니다.
- 데이터베이스의
추천하는 해결책
가장 안전하고 권장되는 해결방안은 ExecutionContext에 한글을 사용하지 않거나, 데이터베이스 쪽에서 UTF-8로의 형식 변경을 고려하는 것입니다. 특히 장기적으로 봤을 때 인코딩을 통일하는 것이 관리 측면에서도 유리합니다.
이 문제와 관련해 유사한 상황이 있는 다른 게시물도 참고하실 수 있습니다:
- ExecutionContext 인코딩 문제와 해결
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.





안녕하세요~ 바쁘실텐데 아침부터 답변 주셔서 정말 감사합니다!!
ExecutionContext 주 목적이 재시작을 위한 상태값이긴 한데.. 편의성을 위해서 넣어두고 후처리로 DB에 로깅을 할려고 했습니다ㅠㅠ
혹시 한글 저장이 필수일 때 시나리오 2: DefaultExecutionContextSerializer로 사내 솔루션 변경이 불가능하다면 하단 방법도 고려해볼만 한가요?
별도 예외 주머니인 JobContexHolder 세팅 후 예외 발생 시 jobContextHolder.set(e.toString); 후 사용
따로 주머니에 담지 않고 JobExecutionListener의 afterJob 메서드에서 jobExcecution.getAllFailureExceptions(); 사용
2가지 방안중에 2안이 좋을 것 같긴합니다.
혹시 다른 방법도 있을까요??