Jump to content
  • Occasional NullPointerException with Scheduled Reports


    mgeise
    • Features: JasperReports Server Product: JasperReports® Server

    Summary

    NullPointerException while running multiple reports thru the report scheduler in JasperReports Server. Failure appears random but occurs most commonly on heavily loaded multi-processor machines.

    Symptom

    The error stack is as the following:

    [toc]
    Job: 422797 (ID: 2865)
    Report unit: /SampleName
    Quartz Job: ReportJobs.job_2865
    Quartz Trigger: ReportJobs.trigger_2863_0
    Exceptions:
    
    An error occurred while executing the report.
    java.lang.NullPointerException
    at sun.font.GlyphLayout$EngineRecord.init(GlyphLayout.java:565)
    at sun.font.GlyphLayout.nextEngineRecord(GlyphLayout.java:439)
    at sun.font.GlyphLayout.layout(GlyphLayout.java:362)
    at sun.font.ExtendedTextSourceLabel.createGV(ExtendedTextSourceLabel.java:267)
    at sun.font.ExtendedTextSourceLabel.getGV(ExtendedTextSourceLabel.java:252)
    at sun.font.ExtendedTextSourceLabel.createLogicalBounds(ExtendedTextSourceLabel.java:163)
    at sun.font.ExtendedTextSourceLabel.getAdvance(ExtendedTextSourceLabel.java:85)
    at java.awt.font.TextLine.init(TextLine.java:245)
    at java.awt.font.TextLine.(TextLine.java:99)
    at java.awt.font.TextMeasurer.makeTextLineOnRange(TextMeasurer.java:467)
    at java.awt.font.TextMeasurer.getLayout(TextMeasurer.java:598)
    at java.awt.font.LineBreakMeasurer.nextLayout(LineBreakMeasurer.java:427)
    at java.awt.font.LineBreakMeasurer.nextLayout(LineBreakMeasurer.java:395)
    at net.sf.jasperreports.engine.fill.TextMeasurer.renderNextLine(TextMeasurer.java:505)
    at net.sf.jasperreports.engine.fill.TextMeasurer.renderParagraph(TextMeasurer.java:338)
    at net.sf.jasperreports.engine.fill.TextMeasurer.measure(TextMeasurer.java:291)
    at net.sf.jasperreports.engine.fill.JRFillTextElement.chopTextElement(JRFillTextElement.java:987)
    at net.sf.jasperreports.engine.fill.JRFillTextField.prepare(JRFillTextField.java:528)
    at net.sf.jasperreports.engine.fill.JRFillElementContainer.prepareElements(JRFillElementContainer.java:344)
    at net.sf.jasperreports.engine.fill.JRFillFrame.prepare(JRFillFrame.java:215)
    at net.sf.jasperreports.engine.fill.JRFillElementContainer.prepareElements(JRFillElementContainer.java:344)
    at net.sf.jasperreports.engine.fill.JRFillBand.fill(JRFillBand.java:346)
    at net.sf.jasperreports.engine.fill.JRFillBand.fill(JRFillBand.java:305)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillColumnBand(JRVerticalFiller.java:1382)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillDetail(JRVerticalFiller.java:692)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReportContent(JRVerticalFiller.java:275)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:117)
    at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:879)
    at net.sf.jasperreports.engine.fill.JRFiller.fillReport(JRFiller.java:123)
    at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:420)
    at com.jaspersoft.jasperserver.api.engine.jasperreports.service.impl.EngineServiceImpl.fillReport(EngineServiceImpl.java:661)
    at com.jaspersoft.jasperserver.api.engine.jasperreports.service.impl.EngineServiceImpl.fillReport(EngineServiceImpl.java:356)
    at com.jaspersoft.jasperserver.api.engine.jasperreports.service.impl.EngineServiceImpl.executeReport(EngineServiceImpl.java:788)
    at com.jaspersoft.jasperserver.api.engine.jasperreports.domain.impl.ReportUnitRequest.execute(ReportUnitRequest.java:60)
    at com.jaspersoft.jasperserver.api.engine.jasperreports.service.impl.EngineServiceImpl.execute(EngineServiceImpl.java:288)
    at com.jaspersoft.jasperserver.api.engine.scheduling.quartz.ReportExecutionJob.executeReport(ReportExecutionJob.java:441)
    at com.jaspersoft.ji.report.options.engine.ReportOptionsExecutionJob.executeReport(ReportOptionsExecutionJob.java:103)
    at com.jaspersoft.jasperserver.api.engine.scheduling.quartz.ReportExecutionJob.executeAndSendReport(ReportExecutionJob.java:369)
    at com.jaspersoft.jasperserver.api.engine.scheduling.quartz.ReportExecutionJob.execute(ReportExecutionJob.java:188)
    at org.quartz.core.JobRunShell.run(JobRunShell.java:195)
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:520)

    Cause

    This issue appears to be caused by a multithreading bug in the Sun AWT code.

    See the following: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6367148

    The issue appears most commonly in very active multi-processor environments.

    Resolution

    Jaspersoft has implemented a workaround to the Sun AWT defect by reattempting the failed action. The fix consists of a custom text measurer that catches NPEs thrown by the JDK GlyphLayout class, and reattempts to measure the text field. The fix is external to JasperReports (note still that JR >= 2.0.3 is required).

    You may need to add the following line to jasperreports.properties file under WEB-INF/classes sub directory to make the code work:

    net.sf.jasperreports.text.measurer.factory=net.sf.jasperreports.engine.util.JdkGlyphFixTextMeasurerFactory
    

    The custom text measurer is itself configurable via the following JR properties:

    1. net.sf.jasperreports.jdk.glyph.fix.text.measurer.attempts - gives the number of attempts to measure a text before giving up; the default value is 20 (which should be enough given that my test never went beyond 2 attempts).
    2. net.sf.jasperreports.jdk.glyph.fix.text.measurer.sleep - the number of milliseconds to sleep between attempts; the default value is 0, i.e. no sleep (according to my tests, no sleep is actually required).
    3. net.sf.jasperreports.jdk.glyph.fix.text.measurer.catch.empty.stakctrace - specifies whether NPEs with no stacktrace should be considered as GlyphLayout exceptions or not.

      This last property is meant to address the fact that the Sun server VM might omit the stacktrace from NPEs thrown from GlyphLayout, which makes it impossible to determine whether en exception was actually thrown from GlyphLayout or not.

    If using a server VM (java -server), this property should be set to true, or the -XX:-OmitStackTraceInFastThrow VM options should be used to force the VM to always set exception stacktraces (more details at http://java.sun.com/j2se/1.5.0/relnotes.html#hotspot).


    User Feedback

    Recommended Comments

    There are no comments to display.



    Guest
    This is now closed for further comments

×
×
  • Create New...