java.awt.AWTError: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable.

mseo39·2026년 9월 13일

TIL

목록 보기
22/22

상황

  • 로컬에서는 엑셀/파일 생성이 정상 동작하지만 리눅스 운영 서버에서만 파일 생성이 실패함

원인

  • Apache POI의 AWT 의존성: 엑셀 생성 시 폰트 크기 계산, 컬럼 너비 자동 조정 등을 처리하기 위해 Java의 AWT 그래픽 툴킷을 내부적으로 호출
  • AWT는 기본적으로 그래픽 카드가 있고 모니터가 연결된 환경을 가정하고 동작함
  • 즉 로컬은 GUI 환경이므로 디스플레이 장치가 연결되어 오류가 안났지만 리눅스 서버는 모니터가 없는 환경이라 AWT가 화면 출력 대상을 찾지 못해 에러가 발생한 것
// org.apache.poi.ss.util.SheetUtil 중 일부
package org.apache.poi.ss.util;

import java.awt.font.FontRenderContext;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.text.AttributedString;
import org.apache.poi.ss.usermodel.*;

public class SheetUtil {

    public static double getCellWidth(Cell cell, int defaultCharWidth, ...) {
        // ...
        AttributedString str = new AttributedString(stringVal);
        copyAttributes(font, str, 0, stringVal.length());

        // ⚠️ 여기서 java.awt.font.TextLayout을 생성합니다.
        // FontRenderContext 및 TextLayout 내부에서 시스템 그래픽스 툴킷(AWT Toolkit)을 조회합니다.
        TextLayout layout = new TextLayout(str.getIterator(), 
                new FontRenderContext(null, true, true));

        // 텍스트의 실제 그래픽 바운딩 박스(너비)를 계산
        return layout.getBounds().getWidth();
    }
}

1. new Font(...) 또는 new TextLayout(...) 호출
2. JVM 내부: java.awt.Toolkit.getDefaultToolkit() 호출
3. 시스템 프로퍼티 점검: java.awt.headless 값이 true인가?
   ├── [True]  -> HeadlessToolkit 인스턴스 로드 (X11 디스플레이 없이 순수 메모리 연산 모드)
   └── [False] -> 리눅스 X11 GUI 툴킷(sun.awt.X11.XToolkit) 로드 시도
                   └── OS 환경변수 DISPLAY(: ':0.0')로 윈도우 서버 소켓 연결 시도
                   └── 연결 실패! -> java.awt.AWTError 발생

해결 방법

  • JVM이 화면 입출력 장치 없이 메모리 상에서만 그래픽/폰트 처리를 수행하도록 Headless모드를 활성화
Tomcat bin/setenv.sh에 JVM 옵션 추가

export CATALINA_OPTS="$CATALINA_OPTS -Djava.awt.headless=true"
profile
하루하루 성실하게

0개의 댓글