Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Java 在 Linux 服務器無圖形界面下報錯 "Can't connect to X11 window server" 根因與三大解決方案

編輯:Linux 教學

Java AWT/Swing/JFreeChart/iText 等圖形操作默認依賴 X11 顯示服務。Linux 服務器通常無桌面環境 (Headless),導致 java.awt.headless=true 未設置時拋出 HeadlessException 或 Can't connect to X11 window server。本文解析根因並提供三大解決方案及容器化最佳實踐。

根因分析

  • Java 圖形操作 (圖片縮放、水印、報表生成、驗證碼) 底層調用 java.awt.GraphicsEnvironment
  • 默認實現 SunGraphicsEnvironment 嘗試連接 X Server (DISPLAY 環境變量)
  • 無圖形界面服務器:DISPLAY 未設置 或 X Server 未運行 → 連接失敗

方案一:啟用 Headless 模式 (推薦,零依賴)


# JVM 啟動參數
-Djava.awt.headless=true

適用場景:純服務端圖形處理 (縮放、水印、報表、驗證碼),無需真實顯示設備。

生效方式:

方案二:安裝虛擬幀緩衝 X Server (Xvfb)


# 安裝
apt-get install xvfb        # Debian/Ubuntu
yum install xorg-x11-server-Xvfb  # RHEL/CentOS

# 啟動虛擬顯示器 :99
Xvfb :99 -screen 0 1024x768x24 &
export DISPLAY=:99

# 或使用 xvfb-run 包裝器
xvfb-run -a java -jar app.jar

適用場景:需真實 X11 功能的場景 (Selenium 測試、特定字體渲染、舊版 JasperReports)。

方案三:使用 Pure Java 圖形庫繞過 AWT (PJA / Java2D 純軟件實現)


# Maven 依賴
<dependency>
    <groupId>com.github.librepdf</groupId>
    <artifactId>openpdf</artifactId>
    <version>1.3.38</version>
</dependency>
# 或 PJA (較老)
<dependency>
    <groupId>com.github.vedeshkin</groupId>
    <artifactId>pja</artifactId>
    <version>3.0</version>
</dependency>

# 系統屬性指向 PJA
-Djava.awt.graphicsenv=com.vedeshkin.awt.PJAGraphicsEnvironment

現代替代:OpenPDF (iText 5 分支)、Apache PDFBox、TwelveMonkeys ImageIO、Thumbnailator 等純 Java 圖形庫,無需 AWT 原生依賴,原生支援 Headless。

Tomcat 具體配置示例 (catalina.sh 修改)


# bin/setenv.sh (推薦,不修改 catalina.sh)
CATALINA_OPTS="$CATALINA_OPTS -Djava.awt.headless=true -Dfile.encoding=UTF-8"

# 若必須修改 catalina.sh (不推薦,升級覆蓋)
# 找到 org.apache.catalina.startup.Bootstrap 行,在前面插入
-Djava.awt.headless=true \

驗證方案生效


# 簡單測試類
public class HeadlessTest {
    public static void main(String[] args) {
        System.out.println("headless=" + System.getProperty("java.awt.headless"));
        System.out.println("GraphicsEnv=" + GraphicsEnvironment.getLocalGraphicsEnvironment().getClass().getName());
        BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = img.createGraphics();
        g.drawString("Test", 10, 50);
        g.dispose();
        ImageIO.write(img, "png", new File("/tmp/test.png"));
        System.out.println("Image written successfully");
    }
}

# 編譯運行
javac HeadlessTest.java
java -Djava.awt.headless=true HeadlessTest

字體缺失導致輸出亂碼/方塊字追加方案


# 安裝開源字體
apt-get install fonts-dejavu-core fonts-liberation2 fonts-noto-cjk  # Debian/Ubuntu
yum install dejavu-sans-fonts liberation-fonts google-noto-cjk-fonts  # RHEL/CentOS

# 註冊字體目錄 (JDK 9+ 模塊化需額外)
# -Djava.awt.fontconfig.properties=...

決策樹:純服務端圖形處理 → -Djava.awt.headless=true (首選);需 Selenium/瀏覽器自動化 → Xvfb + Chrome/Firefox Headless;PDF/報表生成 → 遷移至 OpenPDF/PDFBox/Apache POI 純 Java 庫。徹底擺脫 X11 依賴,才是雲原生 Java 服務的正確姿態。

Copyright © Windows教程網 All Rights Reserved
部署模式配置位置
命令行直啟java -Djava.awt.headless=true -jar app.jar
Systemd 服務Environment="JAVA_OPTS=-Djava.awt.headless=true"
Tomcatbin/setenv.sh: CATALINA_OPTS="$CATALINA_OPTS -Djava.awt.headless=true"
Jettystart.ini: -Djava.awt.headless=true
Spring Bootapplication.yml: spring.main.java-opts: -Djava.awt.headless=true
DockerENV JAVA_OPTS="-Djava.awt.headless=true"
Kubernetesenv: - name: JAVA_OPTS value: "-Djava.awt.headless=true"