前言
- 开发了一个用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缺少字体的问题