【发布时间】:2017-10-22 23:02:53
【问题描述】:
我正在测试环境中运行一个进程,该进程需要 10 多个小时才能运行并使用 Jasper Reports v3.7.5 生成 PDF 文档。
进程经常成功完成,但在某些情况下进程失败并抛出此异常:
20/05/2017 02:45:23.503 ERROR [process-pool-2-thread-20] net.sf.jasperreports.extensions.DefaultExtensionsRegistry - Error instantiating extensions registry for simple.font.families
net.sf.jasperreports.engine.JRRuntimeException: java.io.IOException: Problem reading font data.
at net.sf.jasperreports.engine.fonts.SimpleFontFace.<init>(SimpleFontFace.java:77)
at net.sf.jasperreports.engine.fonts.SimpleFontFamily.createFontFace(SimpleFontFamily.java:316)
at net.sf.jasperreports.engine.fonts.SimpleFontFamily.setNormal(SimpleFontFamily.java:85)
at net.sf.jasperreports.engine.fonts.SimpleFontExtensionHelper.parseFontFamily(SimpleFontExtensionHelper.java:233)
at net.sf.jasperreports.engine.fonts.SimpleFontExtensionHelper.parseFontFamilies(SimpleFontExtensionHelper.java:204)
at net.sf.jasperreports.engine.fonts.SimpleFontExtensionHelper.loadFontFamilies(SimpleFontExtensionHelper.java:173)
at net.sf.jasperreports.engine.fonts.SimpleFontExtensionHelper.loadFontFamilies(SimpleFontExtensionHelper.java:142)
at net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory.createRegistry(SimpleFontExtensionsRegistryFactory.java:63)
at net.sf.jasperreports.extensions.DefaultExtensionsRegistry.instantiateRegistry(DefaultExtensionsRegistry.java:238)
at net.sf.jasperreports.extensions.DefaultExtensionsRegistry.loadRegistries(DefaultExtensionsRegistry.java:213)
at net.sf.jasperreports.extensions.DefaultExtensionsRegistry.loadRegistries(DefaultExtensionsRegistry.java:162)
at net.sf.jasperreports.extensions.DefaultExtensionsRegistry.getRegistries(DefaultExtensionsRegistry.java:132)
at net.sf.jasperreports.extensions.DefaultExtensionsRegistry.getExtensions(DefaultExtensionsRegistry.java:104)
at net.sf.jasperreports.engine.util.JRStyledTextParser.<clinit>(JRStyledTextParser.java:76)
at net.sf.jasperreports.engine.fill.JRBaseFiller.<init>(JRBaseFiller.java:182)
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:78)
at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:624)
at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:605)
...
Caused by: java.io.IOException: Problem reading font data.
at java.awt.Font.createFont0(Font.java:1000)
at java.awt.Font.createFont(Font.java:877)
at net.sf.jasperreports.engine.fonts.SimpleFontFace.<init>(SimpleFontFace.java:69)
... 120 common frames omitted
不久之后,在同一个线程上,记录了以下错误。不过,我不确定它是否相关:
20/05/2017 02:45:23.605 ERROR [process-pool-2-thread-20] my.package.MyClass.NoClassDefFoundError - AbstractReportCreationService.createAndPersistReport(...) threw an error: Could not initialize class sun.awt.X11GraphicsEnvironment
我尝试在 Solaris 5.10 和 5.11 上运行此进程,使用相同的 Java 1.8.0 版本。它随机发生在两者上。我一直在尝试重现错误以找到根本原因,但到目前为止无济于事。
我已阅读 StackOverflow 和 Jaspersoft 社区论坛中报告的类似问题。这些帖子中的大多数都提到了可能阻止进程读取或写入 java 临时目录 (java.io.tmpdir = /var/tmp/) 的权限问题。例如:
The method JasperFillManager.fillReport () throws java.io.Exception
我检查了文件权限,这些都是正确的。当进程成功运行时,它会创建名为+~JF9070759829719582131.tmp 或类似随机名称的临时字体文件。即使进程失败,它也会在/var/tmp/ 目录中留下一些临时字体文件,因此权限似乎不是问题。最重要的是,成功和失败运行之间的权限不会改变。
在 Jaspersoft 社区论坛的这篇帖子中:
http://community.jaspersoft.com/questions/543492/javaioioexception-problem-reading-font-data
建议的解决方案是使用选项启动 Tomcat
-Djava.awt.headless=true
我正在运行的进程使用纯 Java,而不是 Tomcat,但我愿意尝试无头模式。由于问题是随机发生的并且需要很长时间才能运行,因此很难证明这种可能的解决方案实际上可以解决问题。我担心将其部署到生产环境并在那里随机遇到相同的问题。谁能解释一下为什么在无头模式下运行可能会解决问题,或者我应该尝试什么其他可能的解决方案?
【问题讨论】:
-
检查运行 java 进程的用户是否有权访问字体文件。这是实际抛出异常
java.awt.Font#createFont0(int, InputStream, CreatedFontTracker)的方法
标签: java fonts jasper-reports x11