升级JasperReports至7.0.0时Java应用触发JRFontNotFoundException
问题背景
我有一个独立Java应用,内嵌两份12年前用iReports创建的JasperReports报表。因需从Java 8升级至Java 11,同步升级JasperReports。仅通过JasperSoft Studio v7.0.2重新编译.jrxml文件,将生成的.jasper文件替换到src/main/resources目录后,出现如下堆栈错误。我已了解字体扩展相关内容,甚至将字体SansSerif替换为Tahoma,但无效果,必要时可提供.jrxml文件。
错误堆栈
[INFO] 20250331 134709 actionPerformed User clicked 'Reports'. (AppMain.java:447) [INFO] 20250331 134745 actionPerformed User clicked 'Print All...' on route 10. (AppMain.java:1784) Exception in thread "AWT-EventQueue-0" java.lang.ExceptionInInitializerError at net.sf.jasperreports.engine.fill.JRBaseFiller.<init>(JRBaseFiller.java:121) at net.sf.jasperreports.engine.fill.JRVerticalFiller.<init>(JRVerticalFiller.java:77) at net.sf.jasperreports.engine.fill.JRVerticalFiller.<init>(JRVerticalFiller.java:87) at net.sf.jasperreports.engine.fill.JRVerticalFiller.<init>(JRVerticalFiller.java:57) at net.sf.jasperreports.engine.fill.JRFiller.createFiller(JRFiller.java:142) at net.sf.jasperreports.engine.fill.JRFiller.fillReport(JRFiller.java:52) at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:417) at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:378) at com.sgws.bevscan.ui.MyReportViewer.<init>(MyReportViewer.java:49) at com.sgws.bevscan.app.AppMain$29.actionPerformed(AppMain.java:1798) at com.sgws.common.utils.CursorController$1.actionPerformed(CursorController.java:26) at java.desktop/javax.swing.AbstractButton.fireActionPerformed(Unknown Source) at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source) at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source) at java.desktop/javax.swing.DefaultButtonModel.setPressed(Unknown Source) at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source) at java.desktop/java.awt.Component.processMouseEvent(Unknown Source) at java.desktop/javax.swing.JComponent.processMouseEvent(Unknown Source) at java.desktop/java.awt.Component.processEvent(Unknown Source) at java.desktop/java.awt.Container.processEvent(Unknown Source) at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source) at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source) at java.desktop/java.awt.Component.dispatchEvent(Unknown Source) at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source) at java.desktop/java.awt.Window.dispatchEventImpl(Unknown Source) at java.desktop/java.awt.Component.dispatchEvent(Unknown Source) at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source) at java.desktop/java.awt.EventQueue$4.run(Unknown Source) at java.desktop/java.awt.EventQueue$4.run(Unknown Source) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source) at java.desktop/java.awt.EventQueue$5.run(Unknown Source) at java.desktop/java.awt.EventQueue$5.run(Unknown Source) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source) at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source) at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.desktop/java.awt.EventDispatchThread.run(Unknown Source) Caused by: net.sf.jasperreports.engine.util.JRFontNotFoundException: Font ' net/sf/jasperreports/fonts/icons/icons.ttf net/sf/jasperreports/fonts/icons/icons.svg net/sf/jasperreports/fonts/icons/icons.eot net/sf/jasperreports/fonts/icons/icons.woff ' is not available to the JVM. See the Javadoc for more details. at net.sf.jasperreports.engine.util.JRFontUtil.checkAwtFont(JRFontUtil.java:358) at net.sf.jasperreports.engine.fonts.SimpleFontFamily.createFontFace(SimpleFontFamily.java:320) at net.sf.jasperreports.engine.fonts.SimpleFontFamily.setNormal(SimpleFontFamily.java:85) at net.sf.jasperreports.engine.fonts.SimpleFontExtensionHelper.parseFontFamily(SimpleFontExtensionHelper.java:243) at net.sf.jasperreports.engine.fonts.SimpleFontExtensionHelper.parseFontFamilies(SimpleFontExtensionHelper.java:214) at net.sf.jasperreports.engine.fonts.SimpleFontExtensionHelper.loadFontFamilies(SimpleFontExtensionHelper.java:183) at net.sf.jasperreports.engine.fonts.SimpleFontExtensionHelper.loadFontFamilies(SimpleFontExtensionHelper.java:152) at net.sf.jasperreports.engine.fonts.FontExtensionsRegistry.getExtensions(FontExtensionsRegistry.java:55) at net.sf.jasperreports.extensions.DefaultExtensionsRegistry.getExtensions(DefaultExtensionsRegistry.java:110) at net.sf.jasperreports.engine.util.JRStyledTextParser.<clinit>(JRStyledTextParser.java:83) ... 46 more
问题根源
核心问题是JVM找不到net/sf/jasperreports/fonts/icons/icons.ttf等图标字体文件,这是JasperReports字体扩展配置异常导致的,和你替换普通文本字体(SansSerif→Tahoma)无关。
解决步骤
检查字体扩展配置文件
确认项目中存在jasperreports_extension.properties,并配置字体扩展注册信息,示例:net.sf.jasperreports.extension.registry.factory.fonts=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory net.sf.jasperreports.extension.simple.font.families.icons=fonts/icons/fontfamily.xml同时检查
fontfamily.xml的路径和内容是否正确,该文件需定义图标字体的具体信息:<?xml version="1.0" encoding="UTF-8"?> <fontFamilies> <fontFamily name="icons"> <normal>net/sf/jasperreports/fonts/icons/icons.ttf</normal> <pdfEncoding>Identity-H</pdfEncoding> <pdfEmbedded>true</pdfEmbedded> </fontFamily> </fontFamilies>确认字体文件存在
确保icons.ttf等字体文件确实在src/main/resources/net/sf/jasperreports/fonts/icons/目录下,路径和配置完全匹配(Linux环境注意大小写)。匹配JasperReports版本
JasperSoft Studio v7.0.2对应的JasperReports版本要和项目依赖的版本一致,避免编译和运行版本不匹配导致资源加载异常。清理重建项目
清理Maven/Gradle缓存,重新编译打包,确保新的字体文件和配置被正确打包进应用。临时排查方案
如果暂时找不到字体文件,可在fontfamily.xml中注释掉该图标字体配置,或替换为系统已有的字体,先验证报表能否正常运行,再逐步定位问题。
内容的提问来源于stack exchange,提问作者Davidson




