【问题标题】:Concurrent Modification Exception in Jasper ReportJasper 报告中的并发修改异常
【发布时间】:2015-08-16 07:47:30
【问题描述】:

我正在开发一个基于 Java swing 的独立应用程序,我必须将 Jasper 报告打包到 jar 文件中。报告也使用子报告。

当我在 Eclipse IDE 中运行报告时,它运行良好,这意味着所有带有或不带有子报告的报告都在正常运行;但是当我将它们打包到 jar 文件中时,只有没有子报表的报表才能正常工作,而使用子报表的报表会抛出异常-

Exception in thread "Thread-7" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    at java.util.ArrayList$Itr.next(Unknown Source)
    at net.sf.jasperreports.engine.fill.BaseFillHandle.notifyError(BaseFillHandle.java:210)
    at net.sf.jasperreports.engine.fill.BaseFillHandle$ReportFiller.run(BaseFillHandle.java:135)
    at java.lang.Thread.run(Unknown Source)

报告的结构如下目录层次结构-

+ main
|------+ reports
       |--------+ invoice
       |        |--------> invoice_master.jasper
       |        |--------> invoice_sub_report.jasper  
       |---------> end_of_the_day_report.jasper

我的意思是 'end_of_the_day_report.jasper' 在 jar 包中工作正常,但 '/reports/invoice/invoice_master.jasper' 不行,抛出上述异常。

我已将“SUBREPORT_DIR”参数作为“/reports/invoice/”传递给“invoice_master.jasper”报告。

我在我的项目中使用“jasperreports 5.6.0”库。

【问题讨论】:

    标签: java swing jasper-reports


    【解决方案1】:

    好吧,经过大量的测试用例和参考,我找到了上述问题的原因。

    在第一个站点,并发修改似乎很奇怪,似乎是由于某些集合的并发修改。但就我而言,以下策略对我有用-

    1. 当报告是单页时,即使在 jar 包中也可以阅读。但是对于具有多个子报告的报告 在 jar 包中不起作用,因为它是压缩的。你有两个解决方案

      a)您坚决将jasper文件放入jar包中,而不是阅读此处的帖子-

    在您的 Java 代码中使用 Input Stream 加载所有子报表,并将它们传递到参数映射中

    在 iReport 设计器中将这些参数映射到子报表

    JasperReport jasperReport = null;
    JasperReport subReport = null;
    String reportPath = "/reports/invoice/invoice_master.jasper";
    String subReportPath = "/reports/invoice/invoice_sub_report.jasper";
    try {
    //load the the reports
    jasperReport = (JasperReport)JRLoader.loadObject(getClass().getResource(reportPath));
    
    subReport = (JasperReport)JRLoader.loadObject(getClass().getResource(subReportPath));
    
    //pass the subReport object as a parameter to the jasperReport
    Map<String, Object> reportParams = new HashMap<String, Object>();
    params.put("SUB_JASPER", subReport);
    
    //finally pass the parameter map to the report.
    JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, params, connectionOrOtherDataSource);
    //... do something with jasperPrint
    } catch (JRException e) {
        e.printStackTrace();
    }
    

    在你的 Jasper 文件中你应该有 -

    i) 创建报表参数“SUB_JASPER”,参数类设置为net.sf.jasperreports.engine.JasperReport

    ii) 点击子报表,将 Expression Class 属性设置为net.sf.jasperreports.engine.JasperReport,将 Subreport Expression 设置为参数“$P{SUB_JASPER}”。


          b) 您可以灵活地将 jasper 报告放在 jar 包之外,然后阅读以下内容 -

    把你所有的报告放在reports目录或者它的子目录下,jar文件和reports目录都在这个目录下 在同一级别。 如果您的报告使用图像而不是将它们也放在图像目录下的报告目录级别。 所以你的目录结构现在会变成-

        + myapp.jar
        + images
        |--------->image1.png
        + reports
        |--------+ invoice
        |        |--------> invoice_master.jasper
        |        |--------> invoice_sub_report.jasper  
        |--------> end_of_the_day_report.jasper
    


    注意:-image1.png”是jasper 报告中使用的图像。
    当您运行 jar 文件时,包含 jar 文件的目录会自动位于类路径中,因此 报告和图像也在搜索路径列表中。

    希望这对你也有用!!

    【讨论】:

      猜你喜欢
      • 2012-10-07
      • 2012-09-20
      • 2022-01-25
      • 2016-11-19
      • 1970-01-01
      • 1970-01-01
      • 2013-03-12
      相关资源
      最近更新 更多