Simon Nicholls Simon Nicholls - 7 days ago 5
Java Question

Jasper Library - Filling Report Random 'bug'

I've been developing a JAVA application that makes use of Jasper Library (6.3.0). The system is multi-threaded running on a solaris box. For the most part the entire process works quite well, we create xml on the fly to be used as a data source since we need to call lots of different services to build our content.

However, and I don't know how much help Stack Overflow can be here, we've run into a bug/issue which is quite concerning. In 1 out of a 100 or so reports we come across weird formatting issues, where text becomes randomly bold, larger, falling off the side of the page stuff like that. re-running any 'bugged' report proves it's not with that individual report because it'll be fine the second run.

I've outputted the XML at the point of creation and confirm the content looks correct with no random formatting issues or anything like that. So the issue comes at the point of the filling. I've got a couple of hunches that perhaps it's the way we're using Jasper's Api whilst being multi-threaded (performance related) or something to do with fonts. However, if it was either of those I'd expect the issue to arise more often and consistently, but it's random.

I've been going around in circles trying to identify and rule out different scenarios - and my only remaining options seem to be drop building some of the content dynamically and use a different approach to report building. I understand this an incredibly difficult thing to help debug or ask because of it's slightly random nature. How can I work I firstly identify when a report is firstly bugged in this way? And how can I identify the route cause?

Added Code since people were asking for something:

//generate the document with jasper
Document document;
try {
document = JRXmlUtils.parse(new InputSource(new StringReader(xml)));
} catch (JRException e) {
logger.error("Parsing XML has failed, report no:" + id + " " + e.getMessage());
e.printStackTrace();
}

// Passing parameters
Map<String, Object> parameters = new HashMap<>();

parameters.put(JRXPathQueryExecuterFactory.PARAMETER_XML_DATA_DOCUMENT, document);

//put the chosen template ids as parameters
parameters.put("template1", template1.toString());
parameters.put("template2", template2.toString());
parameters.put("template3", template3.toString());

logger.info("Creating report object...");
JRPdfExporter jrPdfExporter = new JRPdfExporter();
JasperPrint jprint;

try {
jprint = JasperFillManager.fillReport("resources/report_source/REPORT.jasper", parameters);
} catch (Exception e) {
logger.error(e.getMessage());
e.printStackTrace();
}

Answer

I'll answer my own question.

I think what my question fails to mention which is actually pretty important is that we're using the HTML component in all our reports, and on investigating further it's just within HTML content that the 'random' formatting happens during mulit-threading.

JASPER forums aren't brilliant on the subject, other than that the HTML component isn't production ready - however after digging further through the HTML component code I now know how it works. The HTML component is using another library to convert the HTML to an image, a SVG to be exact. It then uses this to build the html content. The library it's using is Flying Saucer, which seems fairly popular from having a look a their github, but they do mention that it's sort of a single-thread type of thing - which means the HTML component of Jasper isn't thread safe.

We've come up with two possible solutions, we're looking at either using Flying Saucer separately outside of the multi-threaded application to build the HTML sections into SVG's and then use Jasper's Image object to import the completed images. Or; completely remove all the HTML elements and use the very very basic html markup the Jasper text objects.

I hope this helps anyone else coming across Jasper, and the HTML component!

Comments