前言
- 開發了一個用poi工具導出excel表的接口,本地測試正常,但是部署到線上的測試環境后就一直報接口異常
- 最后發現是docker基礎鏡像源
openjdk
缺少字體管理的問題,記錄一下
先說解決方法和原因:
方法:直接替換DockerFile中的基礎鏡像源:
FROM frolvlad/alpine-java:jdk8-slim
原因:poi中導出excel時會根據字體大小調整列寬,本地開發時使用的時oracl的jdk8,所以沒問題,但是部署到線上后打包的docker使用的open-jdk8-slim鏡像源,此版本早已去除了libfontmanager字體的支持,需要我們自行下載,所以會導致導出時找不到字體管理器報錯!坑爹啊
官方issue:Missing jdk8 packages after #322 #333
其他issue:alibaba/easyexcel
一、 報錯日志
接口:poi插件導出excel的API
環境:
- 線下:
oracle-jdk8
【導出接口正常】- 線上:docker基礎鏡像
open-jdk8-slim
【導出接口異常】報錯棧:
stackTrace: org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.UnsatisfiedLinkError:/usr/local/openjdk-8/lib/amd64/libfontmanager.so: libfreetype.so.6: cannot open shared object file: No such file or directory\n\tat
二、 尋找原因
1. 在網絡上搜索上邊報錯的棧信息,得到以下的可能原因
① Apache POI缺少動態庫libfreetype.so
② Tomcat沒有開啟圖像處理awt
③ Linux服務器缺少POI需要的字體(報錯棧最直觀的體現)
三、 解決思路
1、 嘗試服務器下載對應的字體(無法解決)
- apt -y install libfreetype6-dev
2、 嘗試修改dockerFile文件命令重新構建附帶字體的鏡像(無法解決)
- RUN apt install fontconfig -y --force-yes && apt install --fix-broken -y --force-yes
3、 嘗試使用系統命令修改tomcat使用awt(沒效果,無法解決)
4、 嘗試修改鏡像源(牛逼,輕松解決)
三、 錯誤原因總結
- 線下開發時,使用的是
oracl-jdk:8
版本,在使用poi工具導出excel時,不會存在找不到字體的問題- 然而在使用docker部署到線上時使用的是
openjdk:8-jre-slim
,這個鏡像沒有libfontmanager鏈接庫,會導致poi工具導出excel時調用字體庫失敗並報錯,具體原因可以去最開頭寫的原因中查看官方的issue了解詳情- 最終解決問題所用到的基礎鏡像源來自這篇文章:解決docker alpine缺少字體的問題