Linux 服务器导出报错修复记录:libfontmanager / libfreetype
日期:2026-09-30
服务器:AWS Amazon Linux 2023(SRDAPP570001),JDK8 路径 /opt/jdk8,后端 systemd 部署
涉及模块:后端同步导出(ExcelUtil + POI 4.1.2 SXSSF)
一、现象
-
页面点导出,后端报:
textHandler dispatch failed; nested exception is java.lang.UnsatisfiedLinkError:/opt/jdk8/jre/lib/amd64/libfontmanager.so: libfreetype.so.6: cannot open shared object file -
本地 Windows 环境同样操作完全正常,仅 Linux 服务器报错。
二、根因
- 导出 Excel 时 POI(
SXSSFWorkbook+createFont/setCellStyle+wb.write)会初始化java.awt.Font→sun.font.FontManagerFactory→ 加载 JDK 原生库libfontmanager.so, 该库依赖系统库libfreetype.so.6。 已在本机 JDK8 用-verbose:class实验复现确认:即使代码没有任何 AWT import、headless 模式下,纯 POI 写样式也会触发这条链。 - Amazon Linux 2023 精简安装不带 freetype / fontconfig,导致
UnsatisfiedLinkError。 - 该错误表现为
Handler dispatch failed的原因:ExcelUtil.exportExcel内是catch (Exception e), 而UnsatisfiedLinkError是Error不是Exception,接不住,直接穿透到 DispatcherServlet。
三、修复步骤(Amazon Linux 2023,yum/dnf)
实际安装的包(2026-09-30 已执行成功): freetype-2.13.2-5、fontconfig-2.13.94-2、dejavu-sans-fonts-2.37-16、 google-noto-cjk-fonts-20230817-2(含 google-noto-sans/serif-cjk-ttc-fonts)。
四、踩坑记录
-
ldd显示libjvm.so => not found是正常现象,不要被吓到。libjvm.so 由 JVM 运行时自己 加载(在jre/lib/amd64/server/下,不在系统库路径),所有 JDK 原生库用 ldd 看都是这样。 验证时只关注libfreetype.so.6是否还出现在 "not found" 列表里。 -
装完库必须重启服务。首次
UnsatisfiedLinkError后,JVM 会把sun.awt.X11FontManager永久标记为"初始化失败",同一进程内不再重试,之后所有导出请求都会变成:textNoClassDefFoundError: Could not initialize class sun.awt.X11FontManager这是同一根因的第二阶段表现,不是修错了;重启即恢复。
-
freetype 和 fontconfig/字体要一起装。只装 freetype,下一步常见
NullPointerException at sun.awt.FontConfiguration.getVersion。 -
应用若跑在 Docker 容器里,必须装进容器(镜像或 docker exec),宿主机 yum install 对容器内 JVM 无效。 本次部署为宿主机 systemd 直跑,无此问题。
-
无外网兜底方案:把任意 x86_64 Linux 上的
libfreetype.so.6拷到/opt/jdk8/jre/lib/amd64/下即可(JDK 优先从自己的 lib 目录找,无需配 LD_LIBRARY_PATH); 或恢复标准 JDK8 自带的jre/lib/libfreetype.so(被裁剪过的 JDK 发行版可能缺失)。