OpenJDK 比JDK缺少AWT組件部分功能

Apache POI 中使用SXSSFWorkbook出現Excel導出失敗的異常。

問題堆棧

java.lang.NullPointerException: null
        at sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1264)
        at sun.awt.FontConfiguration.readFontConfigFile(FontConfiguration.java:219)
        at sun.awt.FontConfiguration.init(FontConfiguration.java:107)
        at sun.awt.X11FontManager.createFontConfiguration(X11FontManager.java:774)
        at sun.font.SunFontManager$2.run(SunFontManager.java:431)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.font.SunFontManager.<init>(SunFontManager.java:376)
        at sun.awt.FcFontManager.<init>(FcFontManager.java:35)
        at sun.awt.X11FontManager.<init>(X11FontManager.java:57)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at java.lang.Class.newInstance(Class.java:442)
        at sun.font.FontManagerFactory$1.run(FontManagerFactory.java:83)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.font.FontManagerFactory.getInstance(FontManagerFactory.java:74)
        at java.awt.Font.getFont2D(Font.java:491)
        at java.awt.Font.canDisplayUpTo(Font.java:2060)
        at java.awt.font.TextLayout.singleFont(TextLayout.java:470)
        at java.awt.font.TextLayout.<init>(TextLayout.java:531)
        at org.apache.poi.ss.util.SheetUtil.getDefaultCharWidth(SheetUtil.java:285)
        at org.apache.poi.xssf.streaming.AutoSizeColumnTracker.<init>(AutoSizeColumnTracker.java:117)
        at org.apache.poi.xssf.streaming.SXSSFSheet.<init>(SXSSFSheet.java:89)
        at org.apache.poi.xssf.streaming.SXSSFWorkbook.createAndRegisterSXSSFSheet(SXSSFWorkbook.java:701)
        at org.apache.poi.xssf.streaming.SXSSFWorkbook.createSheet(SXSSFWorkbook.java:722)

根本原因

服務器是使用的JDK是OpenJDK,AWT組件中被簡化了,沒有字體,同時服務器中沒有字體包。而本地一般使用OracleJDK擁有完整的AWT功能。結果常出現本地服務功能正常,生產環境失敗。

修復方案

方案一

直接將JDK更換成完整的版本,不用OpenJDK。

方案二

如果是使用Apache POI導出Excel失敗,可以升級poi的jar版本,在5.2.3版本的時候對這個問題進行了修復。

https://poi.apache.org/changes.html#5.2.3

Type

BUG

Module

Description

使用Apache POI導出Excel數據有BUG_java

66230

SXSSF

SXSSFWorkbook should work even when fonts not installed on OS

方案三

給服務器(CentOS)安裝配置字體

  1. 安裝fontconfig
    在線安裝
yum install fontconfig

離線方法,需要去下載對應的離線安裝包,根據系統版本而定。舉例:

rpm -ivh fontconfig-2.10.95-10.el7.x86_64.rpm  --nodeps --force
  1. 安裝字體ttf-dejavu
    在線安裝
yum install ttf-dejavu

離線方法,需要去下載對應的離線安裝包,根據系統版本而定。舉例:

下載地址:https://packages.msys2.org/packages/mingw-w64-x86_64-ttf-dejavu,取出其中的字體文件,重新打包

使用Apache POI導出Excel數據有BUG_服務器_02

上傳字體:將 字體文件打包上傳到服務器,解壓到 /usr/share/fonts 目錄

刷新字體:執行命令fc-cache --force

查看安裝的字體:執行命令 fc-list

在上述的方案操作之後都是重啓項目。