개요
Windows 환경에서 작성한 설정 파일이나 소스 코드를 Linux 서버에 배포할 때 특수 문자 문제가 발생하는 경우가 있습니다. 대표적으로 UTF-8 BOM(Byte Order Mark)과 Windows 개행문자(CRLF)가 눈에 보이지 않기 때문에 원인 파악이 어렵습니다.
XML 파싱 또는 Hazelcast 세션 연동 환경에서 특수 문자(Special Character)가 포함된 데이터 처리 중 예기치 않은 오류가 발생하는 경우가 있습니다. 대표적으로 Unicode BOM 문자인 (U+FEFF, Zero Width No-Break Space)가 파일 앞에 숨겨져 있거나 XML 내에 포함되어 파싱 실패로 이어지는 케이스입니다. 이 글에서는 해당 문자로 인한 오류 패턴과 해결 방법을 정리합니다.
cvc-complex-type.2.3 오류
09:52:06,504 WARNING [com.hazelcast.web.ClusteredSessionService] (default task-1) Cannot connect to Hazelcast server: cvc-complex-type.2.3: Element 'near-cache' cannot have character [children], because the type's content type is element-only.
09:52:06,962 WARNING [com.hazelcast.web.HazelcastHttpSession] (default task-1) Unexpected error occurred.: java.lang.NullPointerException
at com.hazelcast.web.ClusteredSessionService.updateAttributes(ClusteredSessionService.java:285)
at com.hazelcast.web.HazelcastHttpSession.sessionDeferredWrite(HazelcastHttpSession.java:300)
at com.hazelcast.web.WebFilter.doFilter(WebFilter.java:303)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.jsp.JspFileHandler.handleRequest(JspFileHandler.java:32)
at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
...
- 일반적인 오류 해결법
- XML 태그 정보 누락 여부 재확인
<?xml version="1.0" encoding="UTF-8" ?>
- IDE 문제 – 이클립스 또는 STS 재기동
- 오타 여부 재확인 – 특수문자의 오기입 또는 오탈자로 인해 발생 가능 합니다.
- 그게 아니면…..
- UTF-8 인코딩의 BOM(Byte Order Mark) 문제….
- UTF-8, UTF-16 등의 유니코드 인코딩 방식을 알리기 위한 사인(Signature)으로 사용하기 위한 용도 입니다.
- UTF-8은 BOM 없이도 인코딩 인식이 가능하지만 노트패드등의 윈도우 환경의 일부 에디터가 BOM을 자동으로 추가 하게 되며 눈에 보이지 않는 특수 문자(여백 문자)가 추가 되게 됩니다. 이로 인해 UNIX 환경에서 예상치 않은 cvc-complex-type.2.3 오류가 발생할 수 있습니다.
- 해결 방안
- Notepad++, Ultraeditor, EditPlus 등의 에디터를 이용해 ‘UTF-8 without BOM’ (BOM 없는 UTF-8) 으로 저장
- 개인적으로는 BOM 없는 UTF-8로 저장이 안되어서 태그 앞의 여백 부분을 모두 삭제하여 해결 하였습니다.
- 윈도우에서 코드를 저장할 때는 항상 인코딩에 주의를 해야할 듯 합니다. 🙂
출처
http://blog.wystan.net/2007/08/18/bom-byte-order-mark-problem
https://ko.wikipedia.org/wiki/%EB%B0%94%EC%9D%B4%ED%8A%B8_%EC%88%9C%EC%84%9C_%ED%91%9C%EC%8B%9D
Linux에서 BOM 문자 감지 및 제거
Windows에서 작성된 파일을 Linux 서버에 배포할 때 BOM 문자가 포함된 경우, XML/JSON 파싱 오류나 쉘 스크립트 실행 오류가 발생합니다. Linux에서 BOM 문자를 감지하고 제거하는 방법은 다음과 같습니다.
# 파일에 BOM이 있는지 확인 (UTF-8 BOM = EF BB BF)
hexdump -C target.xml | head -2
# 첫 줄이 "ef bb bf"로 시작하면 BOM 포함
# file 명령으로도 확인 가능
file target.xml
# "UTF-8 Unicode (with BOM) text" 출력 시 BOM 존재
# sed로 BOM 제거 (파일 덮어쓰기)
sed -i '1s/^//' target.xml
# Python으로 BOM 제거
python3 -c "
import codecs
with codecs.open('target.xml', 'r', 'utf-8-sig') as f:
content = f.read()
with codecs.open('target.xml', 'w', 'utf-8') as f:
f.write(content)
print('BOM removed')
"
Visual Studio Code, IntelliJ IDEA 등 현대적인 IDE는 파일 저장 시 BOM 포함 여부를 선택할 수 있습니다. VS Code에서는 우측 하단의 인코딩 표시(예: UTF-8)를 클릭하면 “UTF-8 with BOM”과 “UTF-8” 중 선택할 수 있습니다. 팀 공용 저장소라면 .editorconfig에 charset = utf-8을 지정하여 BOM 없는 UTF-8을 표준으로 적용합니다.
참고
참고 문서: Unicode BOM FAQ · XML 1.0 문자 집합 명세