Java程序在构建时运行但不在胖罐中运行

时间:2014-07-25 17:21:32

标签: java jar jasper-reports

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

但是当我构建一个胖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中,然后我将其添加到类路径中。通过“未找到输入流”错误,我猜这与这些字体有关。但是在正常的清洁和构建过程中一切正常但我无法理解为什么胖罐不起作用。

有什么想法吗?

编辑:非常类似于此Font Extension for barcode in report

5 个答案:

答案 0 :(得分:6)

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

以下是我解决问题的方法。

首先,我使用的工具

  • Jaspersoft Studio创建我的报告6.0.3
  • Jasperreport Library 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中的文件之间存在冲突。罐子,最后一个将被覆盖。

现在要包含我的字体(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>

答案 1 :(得分:2)

为我解决的问题是将jasperreports_extension.properties中包含的jasperreports-6.x.x.jar文件的内容附加到我的自定义jasperreports_extension.properties

问题是在创建胖罐时,jar中的属性文件被覆盖了。显然,JasperReports在运行时合并这两个文件。由于缺少原始内容,因此会导致这种误导性错误。

答案 2 :(得分:0)

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文件中,则必须编写特殊代码来处理此问题。 FileInputStreams不起作用。

答案 3 :(得分:0)

@eoinDub: 从胖罐子的类目录加载报告本身时,我遇到了类似的问题。因此,我使用了“ ... getResourceAsStream ()”。 我做了类似的事情(见下面的代码)。 [实际上,我使用了已编译的* .jasper-我不记得未编译的* .jrxml是否也可以工作。]

        JasperReport report = null;

    InputStream is = MyClass.class.getClassLoader().getResourceAsStream(reportName);
    if (FilenameUtils.isExtension(reportName, "jrxml")) {
        JasperDesign jd = JRXmlLoader.load(is);

        report = JasperCompileManager.compileReport(jd);

    } else {
        report = (JasperReport) JRLoader.loadObject(is);
    }

    JRCsvDataSource ds;
    try {
        ds = new JRCsvDataSource(csvName, csvEncoding);
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
        return;
    }

    ds.setUseFirstRowAsHeader(true);
    ds.setFieldDelimiter(csvDelimiter.charAt(0));

    JasperPrint jprint = JasperFillManager.fillReport(report, reportParams, ds);

    try {
        JasperExportManager.exportReportToPdfFile(jprint, outPDF);
    } catch (Exception e) {
        e.printStackTrace();
    }

答案 4 :(得分:0)

我遇到了同样的问题。在我的项目中,我使用 Maven,我注意到在生成胖 .jar 的最后,它抛出了一条消息

jasperreports_extension.properties already added, skipping

在我在网上看到的关于这个问题的内容中,我发现这个文件在几个库中重复出现,例如:jasperreports 和 jasperfonts;这会导致它们之间发生冲突,而 Maven 会忽略它们。所以我所做的是将我的自定义 jasperreports_extension.properties 文件放在第一个 Maven 依赖文件中,以便此文件设置首先使用它。