openjdk:15-alpine环境下Spring Boot集成Jasper Reports的字体报错问题
问题描述
我知道已有很多类似问题,但未找到与我的场景完全匹配的解决方案。
项目环境
- Spring Boot应用
- pom.xml依赖配置:
<dependency> <groupId>net.sf.jasperreports</groupId> <artifactId>jasperreports</artifactId> <version>6.17.0</version> </dependency> <dependency> <groupId>net.sf.jasperreports</groupId> <artifactId>jasperreports-fonts</artifactId> <version>6.17.0</version> </dependency>
- src/main/resources/jasperreports_extension.properties配置:
net.sf.jasperreports.extension.registry.factory.fonts=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory net.sf.jasperreports.extension.simple.font.families.myfamily=fonts/myfamily.xml
- src/main/resources/fonts/myfamily.xml字体配置:
<?xml version="1.0" encoding="UTF-8"?> <fontFamilies> <fontFamily name="Tahoma"> <normal><![CDATA[fonts/Tahoma/tahoma.ttf]]></normal> <pdfEncoding><![CDATA[Cp1251]]></pdfEncoding> <pdfEmbedded><![CDATA[true]]></pdfEmbedded> <exportFonts/> <locales> <locale><![CDATA[ru_RU]]></locale> </locales> </fontFamily> </fontFamilies>
- 已放入字体文件src/main/resources/fonts/Tahoma/tahoma.ttf
上述配置在本地Adopt-OpenJDK-15环境下运行完全正常。
问题表现
服务器Docker部署时,应用使用openjdk:15-alpine镜像启动,出现两类报错:
- 首次访问时报错:
java.lang.UnsatisfiedLinkError: /opt/openjdk-15/lib/libfontmanager.so: Error loading shared library libfreetype.so.6: No such file or directory (needed by /opt/openjdk-15/lib/libfontmanager.so)
- 第二次及后续每次访问均报错:
java.lang.NoClassDefFoundError: Could not initialize class net.sf.jasperreports.engine.util.JRStyledTextParser] with root cause
已尝试的无效方案
- 给Docker容器添加JAVA_OPT参数:
-Djava.awt.headless=true - 在Docker镜像中安装ttf-dejavu:可解决问题,但不符合需求,不希望引入额外字体依赖
- 切换为非alpine版本的JDK:可解决问题,但必须使用alpine版本,方案不适用
- 将pdfEncoding修改为Identity-H:无效
- 添加default.jasperreports.properties配置:
net.sf.jasperreports.default.font.name=Tahoma net.sf.jasperreports.default.pdf.font.name=Tahoma net.sf.jasperreports.default.pdf.encoding=Cp1252 net.sf.jasperreports.default.pdf.embedded=false
该方案触发新的NPE错误,无有效解决方案。
需求
如何在不额外安装依赖、保留alpine JDK的前提下解决上述报错?
解决方案
错误根源
报错核心原因是Alpine镜像默认未携带libfreetype运行库,OpenJDK的字体管理模块依赖该库完成初始化,触发JasperReports的JRStyledTextParser类初始化失败。你之前安装的ttf-dejavu是字体集合包,附带了大量冗余字体,完全可以通过更轻量的方式解决问题。
可选用方案
方案1:仅安装必要运行库(体积增量<1MB,无冗余内容)
不需要安装任何字体包,仅安装JDK依赖的freetype运行库即可,该包体积仅几百KB,不会带来额外部署负担:
RUN apk add --no-cache freetype
配合你已经内嵌到项目中的Tahoma字体,不需要其他额外配置即可正常运行。
方案2:完全规避系统依赖(无需安装任何apk包)
如果你连运行库都不想安装,可以通过JasperReports配置关闭AWT相关的文本测量逻辑,改用纯Java实现的文本测量器,完全跳过系统字体模块的初始化:
- 在
src/main/resources/jasperreports.properties中添加如下配置:
# 改用纯Java实现的简单文本测量器,不依赖AWT模块 net.sf.jasperreports.text.measurer.factory=net.sf.jasperreports.engine.util.SimpleTextMeasurerFactory # 忽略系统字体缺失错误,仅使用项目内嵌字体 net.sf.jasperreports.awt.ignore.missing.font=true # 禁用系统字体扫描逻辑 net.sf.jasperreports.extension.system.fonts.enabled=false
- 检查所有JasperReports模板,确保所有文本元素的字体明确指定为
Tahoma,不要使用默认字体,避免触发系统字体查找逻辑。
内容的提问来源于stack exchange,提问作者Vladimir Titov
相关产品推荐
相关产品推荐

