Jasper report exporting to text results in java.lang.OutOfMemoryError: Java heap space

Tags: , ,



Currently I am using jasper v 3.7.4

While exporting to any other format (csv,xls,pdf) from the same dataset – I have has no issues.

Exporting to text throws:

java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:3236) at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:118)

Here is my code:

    byte[] bytes = null;
    JRTextExporter  exporter = new JRTextExporter();
    ByteArrayOutputStream txtReport = new ByteArrayOutputStream();
    exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
    exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, txtReport);
    exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, "mytxt.txt");
    exporter.setParameter(JRExporterParameter.CHARACTER_ENCODING, "UTF-8");
    exporter.setParameter(JRTextExporterParameter.CHARACTER_WIDTH, 2.0F);
    exporter.setParameter(JRTextExporterParameter.PAGE_WIDTH, 100.0F);
    exporter.setParameter(JRTextExporterParameter.CHARACTER_HEIGHT, 4.0F);
    exporter.setParameter(JRTextExporterParameter.PAGE_HEIGHT, 50.0F);
    
    exporter.exportReport();
    bytes = txtReport.toByteArray();

    FileOutputStream fos = new FileOutputStream("c:\myfile.txt")
    System.out.println(bytes.length/1024+" Kbytes");
    fos.write(bytes, 0, bytes.length);
    fos.flush();
    fos.close();

I am also using a virtualizer as jasperPrint parameter

 JRFileVirtualizer virtualizer = new JRFileVirtualizer(150);
 virtualizer.setReadOnly(false);
 params.put(JRParameter.REPORT_VIRTUALIZER, virtualizer);

But it does not help, and also the following warning is shown:

WARNING: Parameter “REPORT_VIRTUALIZER” already registered, skipping this one.

Given that csv is also a “text” file and is generated without any problem, it is kind of strange that exporting to text fails.

May be something is wrong with the parameters I provide for the exporter?

Thanks.

Answer

While text and csv may both be text based formats, they’re not the same format and therefore do not take the same amount of space.

Generating anything (usually reports) to memory is hazardous since while it may work in testing, a large report in production causing an OOME will wreak havoc.

Use a real stream when generating things. A FileOutputStream, network stream, any proper stream that doesn’t store things in memory. If you’re using a ByteArrayOutputStream for “real work”, you’re most likely doing something wrong.



Source: stackoverflow