在开发模式下生成JasperReport时出错

时间:2013-05-02 05:40:35

标签: java jasper-reports

我在启动时在程序中初始化报告时遇到问题。 前一段时间,它正常工作。但是当我将JDK 1.7更新17解除对JDK 1.7更新21以及全新安装Netbeans时,存在异常:(

这是错误消息:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
    at sun.font.ExtendedTextSourceLabel.createCharinfo(ExtendedTextSourceLabel.java:609)
    at sun.font.ExtendedTextSourceLabel.getCharinfo(ExtendedTextSourceLabel.java:509)
    at sun.font.ExtendedTextSourceLabel.getLineBreakIndex(ExtendedTextSourceLabel.java:455)
    at java.awt.font.TextMeasurer.calcLineBreak(TextMeasurer.java:325)
    at java.awt.font.TextMeasurer.getLineBreakIndex(TextMeasurer.java:561)
    at java.awt.font.LineBreakMeasurer.nextOffset(LineBreakMeasurer.java:358)
    at net.sf.jasperreports.engine.fill.SimpleTextLineWrapper.measureExactLineBreakIndex(SimpleTextLineWrapper.java:561)
    at net.sf.jasperreports.engine.fill.SimpleTextLineWrapper.measureExactLine(SimpleTextLineWrapper.java:535)
    at net.sf.jasperreports.engine.fill.SimpleTextLineWrapper.nextLine(SimpleTextLineWrapper.java:517)
    at net.sf.jasperreports.engine.fill.TextMeasurer.renderNextLine(TextMeasurer.java:649)
    at net.sf.jasperreports.engine.fill.TextMeasurer.renderParagraph(TextMeasurer.java:454)
    at net.sf.jasperreports.engine.fill.TextMeasurer.measure(TextMeasurer.java:395)
    at net.sf.jasperreports.engine.fill.JRFillTextElement.chopTextElement(JRFillTextElement.java:541)
    at net.sf.jasperreports.engine.fill.JRFillTextField.prepare(JRFillTextField.java:641)
    at net.sf.jasperreports.engine.fill.JRFillElementContainer.prepareElements(JRFillElementContainer.java:331)
    at net.sf.jasperreports.engine.fill.JRFillBand.fill(JRFillBand.java:379)
    at net.sf.jasperreports.engine.fill.JRFillBand.fill(JRFillBand.java:353)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillBandNoOverflow(JRVerticalFiller.java:458)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillPageHeader(JRVerticalFiller.java:421)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReportStart(JRVerticalFiller.java:282)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:151)
    at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:909)
    at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:822)
    at net.sf.jasperreports.engine.fill.JRFiller.fill(JRFiller.java:61)
    at net.sf.jasperreports.engine.JasperFillManager.fill(JasperFillManager.java:446)
    at net.sf.jasperreports.engine.JasperFillManager.fill(JasperFillManager.java:276)
    at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:745)
    at com.ikbiz.gastroscope.controller.ReportController.initReport(ReportController.java:180)
    at com.ikbiz.gastroscope.controller.ReportController.<init>(ReportController.java:111)
    at com.ikbiz.gastroscope.view.PanelScope.<init>(PanelScope.java:32)
    at com.ikbiz.gastroscope.view.PanelEntry.initComponents(PanelEntry.java:199)
    at com.ikbiz.gastroscope.view.PanelEntry.<init>(PanelEntry.java:86)
    at com.ikbiz.gastroscope.view.Application.initComponents(Application.java:203)
    at com.ikbiz.gastroscope.view.Application.<init>(Application.java:35)
    at com.ikbiz.gastroscope.view.Application.getInstance(Application.java:43)
    at com.ikbiz.gastroscope.view.Application.main(Application.java:79)
Java Result: 1

这是我的初始化报告的代码。

public void initReport() {
        try {
            param.put("noMr", "0000");
            param.put("visitCode", "V-199208300000");
            param.put("templateLoco", iReportDir);
            param.put("tools", "Tools");
            param.put("medicine", "Medicine");
            param.put("result", "Data hasil disini");
            param.put("conclusion", "Data kesimpulan disini");
            param.put("suggestion", "Suggestion");
            param.put("SUBREPORT_DIR",iReportDir);

            String imageLoco = iReportDir +"image-sample.jpg";
            for (int i = 0; i < 20; i++) {        
                FileInputStream image = new FileInputStream(imageLoco);
                param.put("imgResult"+(i+1), image);
            }

            param.put("emptyImg", iReportDir+"logo.jpg");

            setTemplate("data/reports/templates/template_1.jasper");

            jasperPrint = JasperFillManager.fillReport(getTemplate(), param, DatabaseUtility.getConnection());
        } catch (JRException ex) {
            System.out.println(ex.getMessage());
        } catch (IOException ioe) {
            System.out.println(ioe.getMessage());
        }
    }

但是,当我建立的时候。 Jar,错误消失了。

请帮助,谢谢之前:)

3 个答案:

答案 0 :(得分:4)

您使用的是Calibri字体吗?我发现这是一个jdk 1.7.0_21错误,似乎特定于Calibri。 尝试将字体切换为Arial,错误应该消失。

如果要修改大量报告和子报告,这可能会有所帮助:

find . *.jrxml -type f -print0 |xargs -0 grep -lZ "Calibri" |xargs -0 sed -i 's/Calibri/Arial/g' 

我有一个应用程序也调用相同的JasperFillManager方法,我可以确认我在jdk 1.7_0_21中看到了相同的堆栈跟踪。如果我将jdk更改为1.7_0_17或1.7_0_07,则不会发生错误。 该类位于rt.jar中,据我所知,源代码不可用。但1.7基于openjdk,非常相似的来源可以在jdk7src找到。

调试应用程序,我可以看到createCharinfo获取一个StandardGlyphVector对象并查询它的字形数,返回0. StandardGlyphVector.getGlyphCharIndices(0,0,null)然后返回一个非null但是空的数组。 sun.font.ExtendedTextSourceLabel代码不检查null或空数组返回情况,并尝试访问正确抛出AIOOBE的数组。

似乎有相关的错误报告here

答案 1 :(得分:3)

我也遇到了这个问题并完成了a bit more testing on this。这是简短的发现,但我也评论了OTN thread

  • 受1.6.0u45和1.7.0u21 Windows JVM影响
  • 仅受Calibri,Calibri Bold,Calibri Bold Italic,Calibri Italic和Cambria Bold字体影响
  • 最有可能在非公开1.6.0u51中修复
  • 已于1.7.0u25修复

答案 2 :(得分:0)

我们将jdk从b24升级到b27版本1.6。

当我们发现同样的问题时,我们通过字体更改修复了以下内容:

在iReport设计器中,对于任何元素,如果我们不指定字体属性(fontName和fontSize),它将被设置为默认值。 希望这会产生问题。

因此,我们“为每个报告中的每个元素指定了字体属性(特别是fontName)”并尝试过。 这解决了这个问题。

根本原因如预期: 在旧版本的jdk中,字体管理器正在处理未指定font属性的元素的默认属性。 在最新版本中,可能是jdk无法处理默认的字体属性。