일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- d
- 목록처리
- 처음 만나는 AI 수학 with Python
- 리눅스
- network configuration
- 코드로배우는스프링웹프로젝트
- 자료구조와 함께 배우는 알고리즘 입문
- resttemplate
- 코드로배우는스프링부트웹프로젝트
- 페이징
- 서버설정
- 친절한SQL튜닝
- baeldung
- 스프링 시큐리티
- 이터레이터
- GIT
- 스프링부트핵심가이드
- 네트워크 설정
- 자료구조와함께배우는알고리즘입문
- 데비안
- 처음 만나는 AI수학 with Python
- 선형대수
- 구멍가게코딩단
- 알파회계
- 티스토리 쿠키 삭제
- /etc/network/interfaces
- Kernighan의 C언어 프로그래밍
- ㅒ
- 자바편
- iterator
- Today
- Total
bright jazz music
리눅스 환경에서 엑셀 다운로드 되지 않는 경우 fontconfig 본문
삼 일째 붙잡고 있던 오류를 해결했다. 로컬 윈도우 환경에서 문제 없이 작동하는 기능이 리눅스 환경에서 작동하지 않는 문제였다. 게시판의 글 목록을 엑셀 파일로 다운받는 기능이었는데, 이 기능은 리눅스 환경에서는 500 에러를 발생시켰다. 로그를 살펴보니 nullPointerException이 주된 원인이었다.
우선은 NullPointerException에 대해 조사했다. 생성되지 않은 객체의 메소드를 사용하려 할 때 발생하는 오류라는 것이 골자였다. 그러나 아무리 찾아 보아도 생성되지 않은 객체의 메소드를 사용하는 코드는 없었다. 의심가는 부분이 있기는 했지만 테스트 해보니 역시 원인이 아니었다.
linux, nullPointerException을 조합한 몇 개의 검색어를 활용해 보아도 만족스러운 답을 찾을 수 없었다. 그러다가 유사한 증상을 호소하는 게시글을 국내 개발자 커뮤니티에서 발견하였다. 하나의 댓글이 나의 눈길을 끌었다.
" xxController.java의 xx번 줄에서 에러났다고 써 있는데요..."
나도 혹시나 하여 로그를 다시 들여다 보았다. nullPointerException과 가까운 곳에 에러가 발생한 행 번호를 알려주는 로그가 존재했다.
내가 의심했던 그 코드였다.
문제가 되었던 코드와 오류 내용을 조합하여 검색해 보니 내 상황과 유사한 증상을 겪은 개발자들의 포스팅이 나타났다. 나는 그들이 문제를 해결한 방법을 내 머신에 테스트 해보았다.
sudo yum install fontconfig
https://www.freedesktop.org/wiki/Software/fontconfig/
리눅스 서버에 fontconfig 유틸리티를 설치했다. 기대 반 의심 반으로 눌렀던 파일 다운로드 버튼은 거짓말처럼 엑셀파일을 생성해 내었다. fontconfig는 리눅스 환경에서 폰트를 사용을 커스터마이징하고 폰트 파일에 관한 접근을 주관하는 유틸리티이다. 이것이 존재하지 않았거나, 또는 윈도우와는 다른 방식으로 폰트를 읽어들이기 때문에 리눅스 머신에서 엑셀 파일을 다운로드 할 수 없었던 것이다. 즉, 객체를 생성하지 않아서가 아니라 객체를 생성할 수 없어서 NullPointerException이 발생했던 것이다.
나는 왜 오류 위치를 알려주는 로그를 살펴보지 않았던 것일까? 최우선으로 참고했어야 하는 코드를 왜 간과한 것일까?
1. 나는 NullPointerException에 너무 매몰되어 있었다. 왠지 늘 똑같아 보이는 상세 로그들을 무시해버렸다.
2. 1번의 이유로, 나는 눈으로 보이는 가장 단순한 사실, 구동 환경 차이의 아니라 내가 모르는 부분에 원인이 있을 거라고 생각하였다.
3. null이 발생하는 이유를 한 가지로 국한하였다. 객체가 생성되지 않은 게 아니라 생성되지 못할 수도 있다는 발상을 하지 못하였다.
이중에서도 가장 눈여겨 봐야하는 것은 1번이다. 2번은 1번에서 파생된 문제이다. 3번은 경험이 짧은 나로서는 피하기 어려운 것이었다. 내게 익숙하지 않은, 마치 그걸 알게 되면 새로운 지평이 열릴 것 같은 개념에 매혹되어 버렸고, 문제 없는 코드만 뚫어져라 보았으니 문제가 해결 될 일이 없다.
따라서 앞으로는 길에 쓰러진 사람을 발견했을 때처럼 문제에 접근하려 한다.
1. 주변 사람들에게 사람이 쓰러져있다고 알린다. (문제 발생 전파)
2. 그 사람의 상태를 살핀다. (가장 눈에 띄는 이상이 무엇인지 파악한다)
3. 그가 말을 할 수 있는 상태라면 그의 말에 귀를 기울인다 ( 로그가 증상에 대해 하는 말을 귀담아 듣는다.)
4. 그가 숨 쉬기가 힘들다고 읊조린다고 하여 목구멍에 손가락부터 집어 넣지 않는다. ( 숨을 쉬지 못하는 데는 여러 가지 이유가 있을 수 있다)