Java 程序在 build 上运行但不在 fat jar 中

标签 java jar jasper-reports

我有一个使用 Jasper Reports API 生成 PDF 的 Java 应用程序。它构建良好,但我必须通过 Netbeans/iReport 插件添加一些字体,以便它们在导出 PDF 时显示。在清理和构建时它很好,一切正常。

但是当我构建一个 fat jar(通过 build.xml 中的一些 package-for-store 行)时,报告不会运行。通过终端运行时,我收到此错误(对不起,文字墙):

Exception in thread "AWT-EventQueue-0" java.lang.ExceptionInInitializerError
    at net.sf.jasperreports.engine.fill.JRBaseFiller.<init>(JRBaseFiller.java:124)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.<init>(JRVerticalFiller.java:89)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.<init>(JRVerticalFiller.java:104)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.<init>(JRVerticalFiller.java:62)
    at net.sf.jasperreports.engine.fill.JRFiller.createFiller(JRFiller.java:179)
    at net.sf.jasperreports.engine.fill.JRFiller.fill(JRFiller.java:108)
    at net.sf.jasperreports.engine.JasperFillManager.fill(JasperFillManager.java:668)
    at net.sf.jasperreports.engine.JasperFillManager.fill(JasperFillManager.java:649)
    at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:971)
    at ie.orderofmalta.OMFinancialsForm.yTDReportBtnActionPerformed(OMFinancialsForm.java:283)
    at ie.orderofmalta.OMFinancialsForm.access$700(OMFinancialsForm.java:30)
    at ie.orderofmalta.OMFinancialsForm$8.actionPerformed(OMFinancialsForm.java:163)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.AbstractButton.doClick(AbstractButton.java:376)
    at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:833)
    at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:877)
    at java.awt.Component.processMouseEvent(Component.java:6505)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3320)
    at java.awt.Component.processEvent(Component.java:6270)
    at java.awt.Container.processEvent(Container.java:2229)
    at java.awt.Component.dispatchEventImpl(Component.java:4861)
    at java.awt.Container.dispatchEventImpl(Container.java:2287)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
    at java.awt.Container.dispatchEventImpl(Container.java:2273)
    at java.awt.Window.dispatchEventImpl(Window.java:2719)
    at java.awt.Component.dispatchEvent(Component.java:4687)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
    at java.awt.EventQueue.access$200(EventQueue.java:103)
    at java.awt.EventQueue$3.run(EventQueue.java:694)
    at java.awt.EventQueue$3.run(EventQueue.java:692)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
    at java.awt.EventQueue$4.run(EventQueue.java:708)
    at java.awt.EventQueue$4.run(EventQueue.java:706)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
Caused by: net.sf.jasperreports.engine.JRRuntimeException: net.sf.jasperreports.engine.JRException: Input stream not found at : fonts/fontsfamily1406301744789.xml
    at net.sf.jasperreports.engine.fonts.SimpleFontExtensionHelper.loadFontFamilies(SimpleFontExtensionHelper.java:188)
    at net.sf.jasperreports.engine.fonts.FontExtensionsRegistry.getExtensions(FontExtensionsRegistry.java:56)
    at net.sf.jasperreports.extensions.DefaultExtensionsRegistry.getExtensions(DefaultExtensionsRegistry.java:110)
    at net.sf.jasperreports.engine.util.JRStyledTextParser.<clinit>(JRStyledTextParser.java:83)
    ... 50 more
Caused by: net.sf.jasperreports.engine.JRException: Input stream not found at : fonts/fontsfamily1406301744789.xml
    at net.sf.jasperreports.repo.RepositoryUtil.getInputStreamFromLocation(RepositoryUtil.java:159)
    at net.sf.jasperreports.engine.fonts.SimpleFontExtensionHelper.loadFontFamilies(SimpleFontExtensionHelper.java:183)
    ... 53 more

当我添加字体时,我将它们添加到一个 jar 中,然后将其添加到类路径中。通过“未找到输入流”错误,我猜这与这些字体有关。但是在正常的清理和构建过程中一切正常,但我不明白为什么 fat jar 不起作用。

有什么想法吗?

编辑:与此非常相似 Font Extension for barcode in report

最佳答案

我被同样的问题困扰了两天,找不到任何可以帮助我的东西。我希望这可以帮助任何面临同样问题的人。

这是我解决问题的方法。

首先是我正在使用的工具

  • 用于创建我的报告的 Jaspersoft Studio 6.0.3
  • Jasperreport 库 6.0.3
  • Arial Unicode MS,嵌入字体
  • Netbeans 8.0.2

因此,首先我修改了 jasperreports-6.0.3.jar 中的文件 jasperreports_extension.properties 并包含了以下几行

net.sf.jasperreports.extension.registry.factory.simple.font.families=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
net.sf.jasperreports.extension.simple.font.families.dejavu=net/sf/jasperreports/fonts/fonts.xml

由于某种原因,当我构建我的 jar 文件时,jasperreports-6.0.3.jar 中的 jasperreports_extension.properties 文件与 jasperreports-fonts-6.0.3 中的文件之间存在冲突。 jar 和最后一个将被覆盖。

现在为了包含我的字体 (Arial Unicode MS),我编辑了文件 /net/sf/jasperreports/fonts/fonts.xml 并插入了以下代码:

<fontFamily name="Arial Unicode MS">
    <normal>net/sf/jasperreports/fonts/ArialUnicodeMS/ARIALUNI.TTF</normal>
    <pdfEncoding>Identity-H</pdfEncoding>
    <pdfEmbedded>true</pdfEmbedded>
    <exportFonts>
    </exportFonts>
</fontFamily>

在此之后,我将我的字体包含在 jasperreports-fonts-6.0.3.jar 中。

enter image description here

现在这非常重要,当您创建 jar 文件时,请确保在提取 jasperreports-6.0.3.jar 之前提取 jasperreports-fonts-6.0.3.jar。

这是我的build.xml

<target name="-post-jar">
    <jar jarfile="dist2/Reports.jar">
        <zipfileset src="${dist.jar}" excludes="META-INF/*;*.jar;*.txt;*.html" />
        <zipfileset src="lib/jetty-all-9.0.3.v20130506.jar" excludes="META-INF/*;*.txt;*.html" />

        <zipfileset src="lib/lib/jasperreports-javaflow-6.0.3.jar" excludes="META-INF/*;*.txt;*.html" />
        <zipfileset src="lib/jasperreports-fonts-6.0.3.jar" excludes="META-INF/*;*.txt;*.html" />
        <zipfileset src="lib/jasperreports-6.0.3.jar" excludes="META-INF/*;*.txt;*.html" />

        <zipfileset src="lib/mysql-connector-java-5.1.34-bin.jar" excludes="META-INF/*;*.txt;*.html" />
        <zipfileset src="lib/commons-javaflow-20060411.jar" excludes="META-INF/*;*.txt;*.html" />
        <zipfileset src="lib/servlet-api-2.4.jar" excludes="META-INF/*;*.txt;*.html" />
        <zipfileset src="lib/javax.servlet-3.0.jar" excludes="META-INF/*;*.txt;*.html" />
        <zipfileset src="lib/commons-logging-1.1.1.jar" excludes="META-INF/*;*.txt;*.html" />
        <zipfileset src="lib/commons-collections-3.2.1.jar" excludes="META-INF/*;*.txt;*.html" />
        <zipfileset src="lib/ant-1.7.1.jar" excludes="META-INF/*" />
        <zipfileset src="lib/groovy-all-2.0.1.jar" excludes="META-INF/*" />
        <zipfileset src="lib/commons-digester-2.1.jar" excludes="META-INF/*" />

        <zipfileset src="lib/itextpdf-5.5.0.jar" excludes="META-INF/*" />
        <zipfileset src="lib/itext-pdfa-5.5.0.jar" excludes="META-INF/*" />
        <zipfileset src="lib/apache-commons-lang.jar" excludes="META-INF/*" />
        <zipfileset src="lib/com.lowagie.text-2.1.7.jar" excludes="META-INF/*" />

        <zipfileset src="lib/commons-beanutils-1.9.0.jar" excludes="META-INF/*" />

        <manifest>
              <attribute name="Main-Class" value="Jetty"/>
        </manifest>
    </jar>
</target>

关于Java 程序在 build 上运行但不在 fat jar 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24961180/

相关文章:

java - 什么是用于搜索的 Retrofit OR 运算符

java - 更新 jar 中的 .class 文件会引发异常

java - JasperReport在Xlsx和Xls中生成不可读的内容

java - 如何在 Jasper Server 5.6 中启用日志记录?

java - 用于 hadoop mapreduce 的 jar

jasper-reports - 为什么组在报告中以不同的顺序出现?

Java:如何遍历类型链接列表的数组并将它们附加到数组

java - 对 Collection<V> 和 Set<K> 进行排序

java - 如何从Java中的不同类获取对象的名称

java - jitpack 将构建工件下载到哪里?