thumbnail
📌 예기치 않은 버그 해결기
Error
2025.06.26.

📌 예기치 않은 버그 해결기

고장 난 시스템에서 정상 작동까지의 여정

🧭 들어가며

개발을 하다 보면 정말 ‘이건 말도 안 돼’ 싶은 버그를 만나곤 한다. 로컬에서는 분명 잘 되던 코드가 배포하자마자 망가지는 일, CLI에선 되는데 GUI에선 안 되는 현상, JSON 응답이 두 번 오는 이상한 상황까지… 이번 글에서는 내가 실제로 겪은 기묘한 오류들과 그것을 해결하기 위한 분투의 기록을 남겨본다.


🐞 1. CLI에선 멀쩡한데, GUI에서는 안 돼?

문제 상황

어느 날, eXbuilder6 기반의 행정 시스템에서 특정 기능을 CLI로 실행하면 잘 작동했는데, 실제 GUI에서는 결과가 반영되지 않는 이상한 문제가 발생했다. 콘솔 로그로는 정상. API 응답도 성공. 그런데 UI에선 아무 변화가 없다?

분석 과정

  • 초기엔 전송된 파라미터를 의심했지만 로그상 문제 없음.
  • 의심을 좁히다 보니, lookup("control").value = ... 코드가 비동기 이벤트 이전에 실행되고 있었다.
  • GUI 환경에서는 DOM 초기화 타이밍이 CLI와 달라 동작 순서가 달라졌던 것.

해결 방법

GUI에서 컨트롤 초기화가 완료된 후 실행되도록 onLoad 이후로 로직을 분리했고, 상태 변경은 callback 안에서만 수행하도록 리팩토링하였다.

🚀 교훈: CLI와 GUI는 실행 컨텍스트가 다르다. UI 요소가 개입되면 항상 렌더 타이밍을 고려하자.


🐛 2. JSON 응답이 두 번? 제우스의 저주

문제 상황

로컬 톰캣에서는 JSON 응답이 정상적으로 { "success": true } 한 번만 내려왔는데, 운영서버(JEUS)에선 다음과 같은 두 개의 JSON이 연속으로 내려왔다.

{"test":{"exist":"Y","success":true}}{"test":{"exist":"Y","success":true}}

분석 과정

  • 필터나 인터셉터에서 두 번 호출되는지 확인 → 이상 없음.
  • PrintWriter를 사용한 응답 처리에서 getWriter()를 두 번 호출한 흔적 발견.
  • JEUS는 응답 버퍼 처리 방식이 다르기 때문에, getWriter() 두 번 호출 시 flush 전에 중복 출력 가능성 있음.

해결 방법

  • 응답 처리 공통 모듈을 작성하여 response.getWriter().write(...) 호출을 한 번으로 제한.
  • 중간에 응답이 이미 커밋되었는지도 체크하도록 개선.

🔎 교훈: 운영 환경의 WAS(JEUS, WebLogic 등)는 로컬과 다르게 응답 버퍼 처리를 하므로, 모든 I/O는 한 번만, 신중하게!


🔧 3. 개발과 운영 환경의 데이터소스가 다르게 동작?

문제 상황

개발 환경에서는 잘 동작하는 DAO 쿼리가 운영에서는 계속 실패. java:comp/env/techdom.ds 로 설정했는데, JNDI에서 자꾸 not found 오류가 발생했다.

분석 과정

  • 로컬 context.xml, web.xml, JEUS의 JNDI 설정 모두 비교.
  • 알고 보니, 운영에서는 global context에 설정돼 있어 상대경로(comp/env/...)가 통하지 않았다.

해결 방법

  • lookup("java:/techdom.ds") 방식으로 절대 경로로 변경.
  • 또는 서버 측 JNDI 설정을 comp/env 하위로 맞춤.

🛠️ 교훈: JNDI는 환경마다 상대 경로가 달라질 수 있다. WAS 설정을 먼저 확인하고 코드를 맞추자.


🚨 4. CLEOPATRA XML 변환 시 GROUP 태그가 안 나와?

문제 상황

Figma JSON을 CLEOPATRA XML로 변환하는 도구에서 GROUP 노드가 있음에도 불구하고 .clx 파일에 <cl:grid>가 생성되지 않음. 더 이상한 건 어떤 경우엔 중복 생성되기도 함.

분석 과정

  • 부모 → 자식 순으로 처리되는 방식에서 GROUP이 두 번 호출됨.
  • 중간에 visible 속성이 false로 설정된 것도 무시하지 않고 처리한 게 문제.

해결 방법

  • visible == false 인 경우 변환 제외하도록 예외 처리 추가.
  • 이미 생성된 GRID의 ID를 Map에 저장해 중복 방지.

💡 교훈: 변환 과정에선 명시적으로 제외 조건을 먼저 걸어두고, 변환 조건을 점진적으로 확장하는 것이 안정적이다.


🏁 마치며

이번에 겪었던 문제들은 하나같이 “설마 이게 문제일까?” 싶은 것들이었다. 하지만 결국엔 로그를 정리하고, 상황을 하나씩 좁히며 핵심을 찾아냈다.
프로젝트가 클수록, 환경이 복잡할수록 이런 오류는 자주 생기기 마련이다. 중요한 건, 당황하지 않고 하나씩 차분히 분석하고 기록하는 것.

버그는 ‘기억’을 지우지만, 기록은 ‘지식’을 만든다.


🧷 태그: #버그해결기 #JEUS #JSON #JNDI #GUI오류 #Figma변환기

🖥️ 브라우저가 HTML을 불러온 뒤, JavaScript는 무슨 일을 할까?
🖥️ 브라우저가 HTML을 불러온 뒤, JavaScript는 무슨 일을 할까?
2025.07.14.
Web
Html
JavaScript
JavaScript의 기나긴 여정
🖥️ HTML이 브라우저에 그려지는 여정
🖥️ HTML이 브라우저에 그려지는 여정
2025.07.10.
Web
Html
HTML의 기나긴 여정
🧵 Spring MVC 이야기
🧵 Spring MVC 이야기
2025.07.07.
Web
DispatcherServlet이 들려주는 웹 요청 여정
Next.js + Vercel에서 ISR 업데이트 지연 문제 해결기
Next.js + Vercel에서 ISR 업데이트 지연 문제 해결기
2025.06.24.
Next.js
Vercel
ISR의 캐싱 구조와 업데이트 반영 딜레이 문제, 그리고 Edge 함수와 캐싱 전략으로 개선한 과정

Thank You for Visiting My Blog, Have a Good Day 🌿

© 2024 Developer LIM.