Jump to content

How well does Jasper handle large amounts of text?


fahim_a

Recommended Posts

Hello!

Let me start off by providing some contextual information. I've been using a combination of Jasper reports 3.5.1 and the Dynamic Jasper 3.0.8 library to help me let users export data from any regular Swing JTable (i.e. JDK 1.5.0.17) in my application. I have an export button that creates the Jasper design dynamically (hence why I'm using DynamicJasper to make my life easier), fills it in, launches a customized JRViewer (customized in the sense I've added email support and removed exporter file formats I'm not interested in).

This setup works just fine ordinarily; for extremely large exported reports I'm even using a virtualizer.

 

So here comes my problem: in certain scenarios, I have a specialized table that has cell values where the String length exceeds 10K (average around ~4k). This is on a JTable with say 30 odd or so rows. Note, I'm not talking about the end result report size; I'm talking about individual cell values being very very large. When I try exporting this JTable, it takes virtually forever (and I mean virtually here since I've seen it run for 12 hours+ before I just give up and shutdown the app). What I think is happening is Jasper is overflowing page after page as it tries to fit in these large values (and sometimes there's multiple columns on multiple rows where such values exist) . I've added a thread dump of the relevant portion where jasper seems extraordinarily busy as it fills the report.

 

Any suggestions or recommendations?

 

Regards, 

Fahim

Code:
Thread [Thread-19] (Suspended)		SunLayoutEngine.nativeLayout(Font2D, FontStrike, float[], int, int, char[], int, int, int, int, int, int, int, Point2D$Float, GlyphLayout$GVData) line: not available [native method]		SunLayoutEngine.layout(FontStrikeDesc, float[], int, int, TextRecord, boolean, Point2D$Float, GlyphLayout$GVData) line: 130		GlyphLayout$EngineRecord.layout() line: 609		GlyphLayout.layout(Font, FontRenderContext, char[], int, int, int, StandardGlyphVector) line: 430		ExtendedTextSourceLabel.createGV() line: 267		ExtendedTextSourceLabel.getGV() line: 252		ExtendedTextSourceLabel.createLogicalBounds() line: 163		ExtendedTextSourceLabel.getAdvance() line: 85		TextLine.init() line: 245		TextLine.<init>(TextLineComponent[], float[], char[], int, int, int[], byte[], boolean) line: 99		TextMeasurer.makeTextLineOnRange(int, int) line: 467		TextMeasurer.getLayout(int, int) line: 598		LineBreakMeasurer.nextLayout(float, int, boolean) line: 427		LineBreakMeasurer.nextLayout(float) line: 395		TextMeasurer.renderNextLine(LineBreakMeasurer, AttributedCharacterIterator) line: 603		TextMeasurer.renderParagraph(AttributedCharacterIterator, int, String) line: 436		TextMeasurer.measure(JRStyledText, int, int, boolean) line: 373		JRFillTextField(JRFillTextElement).chopTextElement(int) line: 1006		JRFillTextField.prepare(int, boolean) line: 536		JRFillBand(JRFillElementContainer).prepareElements(int, boolean) line: 346		JRFillBand.fill(int, boolean) line: 346		JRFillBand.fill(int) line: 305		JRVerticalFiller.fillColumnBand(JRFillBand, byte) line: 1398		JRVerticalFiller.fillDetail() line: 692		JRVerticalFiller.fillReportContent() line: 275		JRVerticalFiller.fillReport() line: 117		JRVerticalFiller(JRBaseFiller).fill(Map) line: 899		JRVerticalFiller(JRBaseFiller).fill(Map, JRDataSource) line: 821		JRFiller.fillReport(JasperReport, Map, JRDataSource) line: 89		JasperFillManager.fillReport(JasperReport, Map, JRDataSource) line: 628		DynamicJasperHelper.generateJasperPrint(DynamicReport, LayoutManager, JRDataSource, Map) line: 235		NNDefaultJRManager.generateJPs(String, Map<String,Object>, JTable) line: 323		NNDefaultJRManager.showNNReport(Window, String, Map<String,Object>, NNTable) line: 304		NNDefaultJRManager.showReport(Window, String, Map<String,Object>, JTable) line: 291		NNActionExportTable$1.doNonUILogic() line: 111		NNActionExportTable$1(SwingWorkerVariant).construct() line: 113		SwingWorkerVariant.access$000(SwingWorkerVariant) line: 14		SwingWorkerVariant$2.run() line: 69		Thread.run() line: 595	
Link to comment
Share on other sites

  • Replies 7
  • Created
  • Last Reply

Top Posters In This Topic

JR measures all texts in a report to determine how much of them fit or how much the element needs to stretch in order to fit the entire text.  This is not a cheap operation (it's usually where the fill process spends most of the time), but I don't think it should take that much.  I filled a report with 30 10k Strings in a few seconds on my old desktop machine.

So there's probably something else that happens in your case.  There are cases when the JR engine goes into infinite loops (usually report design problems), but when that happens the memory is usually exhausted pretty fast.

You can enable debug logging for JR and watch the logs to get a high level idea on what it does.

Regards,

Lucian

 

Link to comment
Share on other sites

 Wow, awesome! Thanks, that definitely seems to have improved things...took ~30 seconds in total but at least it completed. /tools/fckeditor/editor/images/smiley/msn/teeth_smile.gif

So what I'm doing now is taking the JasperPrint object generated by DynamicJasper (and why they're hard coding jElement.setPrintWhenDetailOverflows(true) without letting me set an option in their column object is something I guess I'll have to raise with them), and then iterate over the detail band's elements and set the option to false.

That being said, I'm not a big fan of how this gets rendered in the JRViewer; I liked how things were before (well, at least when I did manage to get the report filled in!) where I could see at least see the first few columns (which usually included a row "key" of some kind) on every page where one/more columns on the same row overflowed.

Is this something that will/can be addressed?

Thanks a million!

/f

Link to comment
Share on other sites

  • 1 month later...

 Hi Lucian,

Sorry for the delay in getting back to you (XMas break, vacation, diverted with other stuff etc. etc.). Please refer to page 2 of the attached pdf output. More of a visual issue, so something that's not a big deal.

So it turns out the original issue has popped up again; I'm trying to characterize what's different this time around. But at least the thread isn't just looping around and yes the memory is now getting exhausted way quicker.

So similar reports when successfully generated are still taking about 46 seconds; however, some users are indicating that they are seeing the out of memory dialogs now.

Any suggestions?

Cheers,

Fahim

P.S. I'm tempted to even investigate ditching DynamicJasper and creating these designs on the fly by myself, but not sure how much time/effort I can allocate to this, so I'll stick with DJ for now

Link to comment
Share on other sites

  • 2 weeks later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...