JasperReports Ultimate Guide - Sample Reference - Schema Reference - Configuration Reference - API (Javadoc)

JasperReports - Virtualizer Sample (version 6.5.1)

Shows how very large reports could be generated using a report virtualizer to optimize memory consumption.

Download All Sample Source Files
Browse Sample Source Files on Git

Main Features in This Sample

Generating Very Large Documents Using Report Virtualizers


Generating Very Large Documents Using Report VirtualizersDocumented by Luke Shannon

Description / Goal
How to generate very large documents using report virtualizers that optimize memory consumption.


What is Virtualization?
A JasperReport goes through 3 stages in its life cycle:
  1. Compilation
  2. Filling
  3. Exporting
In each stage objects are generated in memory. During the filling stages especially many objects
can be generated as data is processed through the report logic populating multiple pages
and the elements within.
In a situation such as this, there is always the risk of an Out of Memory error before the Filling
of the report has concluded.
Virtualization is a feature that allows for some of the objects that would be stored in memory during
the filling stage to be stored on the file system instead.
The virtualizer is a simple interface JRVirtualizer
There are currently three implementations of this interface:
  1. JRFileVirtualizer
  2. JRSwapFileVirtualizer
  3. JRGzipVirtualizer
Each of this will be discussed in greater detail in the proceeding sections of this document.

Running the Sample
Ant is required. By running 'ant --version' you will be able to check if ant is set up on your system (at least version 1.5 is required):
    C:\>ant -version Apache Ant version 1.8.0 compiled on February 1 2010
You can obtain ant from http://ant.apache.org/, instructions for installation can be found there as well.

Starting the Data Source
In a command prompt/terminal window browse to the demo/hsqldb folder of the JasperReports source and run the command 'ant runServer'.
Leave window/terminal running (see below for sample output).
    C:\js-workspace\jasperreports\demo\hsqldb>ant runServer
	Buildfile: C:\js-workspace\jasperreports\demo\hsqldb\build.xml

     [java] [Server@83cc67]: [Thread[main,5,main]]: checkRunning(false) entered
     [java] [Server@83cc67]: [Thread[main,5,main]]: checkRunning(false) exited
     [java] [Server@83cc67]: Startup sequence initiated from main() method
     [java] [Server@83cc67]: Loaded properties from [C:\js-workspace\jasperreports\demo\hsqldb\server.properties]
     [java] [Server@83cc67]: Initiating startup sequence...
     [java] [Server@83cc67]: Server socket opened successfully in 19 ms.
     [java] [Server@83cc67]: Database [index=0, id=0, db=file:test, alias=] opened sucessfully in 1104 ms.
     [java] [Server@83cc67]: Startup sequence completed in 1125 ms.
     [java] [Server@83cc67]: 2010-03-10 11:32:30.423 HSQLDB server 1.8.0 is online
     [java] [Server@83cc67]: To close normally, connect and execute SHUTDOWN SQL
     [java] [Server@83cc67]: From command line, use [Ctrl]+[C] to abort abruptly
Generating the Report
Open up a separate command prompt/terminal window and browse to the root directory of the sample.
By running 'ant -p' you will be presented with a list of options available. Of interest in this list is all the exporters available for testing.
Each export type will generate a output type in the build/report folder.
By running the command 'ant' the following actions will be performed:
  • All java code will be compiled to produce class files.
  • JRXML fills will be compiled by JasperReports to produce a .jasper file (this is a serialized version of a JasperReports object).
  • The report will be filled with data and the resulting object, JasperPrint, will be serialized to the file system as a .jrprint.
  • All the exporters the sample is configured to test will run.

You can now run 'ant view' to see a version of the report in the JasperViewer (a Swing report viewer contained in the JasperReports package which can be used to view a .jrprint object).
Each of the these task can be ran separately as well:
  • ant clean - removes all generated files.
  • ant javac - compiles all java code, this should be done before running further tasks.
  • ant compile - compiles the JRXML generating a .jasper file.
  • ant fill - fills the report with data, some reports use the empty data source, others use the HSQL DB and other an inline data source. A .jrprint object is generated in this step.
  • ant view - opens the report in the JasperViewer
  • ant pdf - generates a PDF (other exporters are available run 'ant -p' for a full list)
Note: All generated files can be found in build/reports.
You now have a working version of the report you can review.

Configuring Virtualization
Virtualization is not configured in the JRXML. The details around the implementation of the virtualizer can be seen in the sample Java application that is used
to run the report: VirtualizerApp.java.
In the fillReport() method we can see where the virtualizer is instantiated:
// creating the virtualizer
JRFileVirtualizer virtualizer = new JRFileVirtualizer(2, "tmp");
The JRFileVirtualizer is created with a maxSize of 2 and "tmp" as the name of the directory to store data.
This means once 2 pages of the filled report have been created in memory, the virtualizer will begin to store
the data required during the filling in the "tmp" directory.
A single instance of this object can be shared over multiple reports. However, this does mean that the max page
number will be respected for all reports that are generated simultaneously.
In the fillReport(JRFileVirtualizer virtualizer) method we can see how the virtualizer is configured for
use during the filling process:
//Preparing parameters
Map parameters = new HashMap();
parameters.put(JRParameter.REPORT_VIRTUALIZER, virtualizer);
The virtualizer must be configured as a parameter passed in during filling.

Types of Virtualizers

As described above the JRFileVirtualizer works with temporary files on disk. It has a built in mechanism
for cleaning up these temp files after they are no longer needed. However when the clean up of these files
occurs may vary (it depends on when the virtualizer reference is garbaged collected by the JVM).
To control when virtualization occurs there is a cleanup() method available that can be called to remove the
files immediatly.

Similar to the JRFileVirtualizer except that rather than creating a file per virtualized page, as the
JRFileVirtualizer does, it shares a single swap file among all report filling processes configured
to use the virtualizer.
A JRSwapFile has to be instantiated and passed into the JRSwapFileVirtualizer.
When creating the JRSwapFile the targer directory, size of the file and rate at
which the file can grow should its current size become insufficient, are all specified.

Using this virtualizer the results in the pages created in memory during filling to be compressed
using the GZIP algorithm. Thus greatly reducing the amount of memory required.

When to use Virtualization
Virtualization will result in slowed performance for larger reports (the JRGzipVirtualizer doesn't write to the
to the file system so its effect on report filling time will be less than the other virtualizers).
However, using virtualization might mean the difference between waiting a longer time to get a report
or getting a out of memory error and no report.
Setting the maxPages in memory is key. Setting the value too low will result in virtualization occuring when it is not necessary.
Setting it too high could result in an out of memory exception occuring before virtualization has a chance to start. Picking the
correct value for a given system will require some trial and error.

Further Resources:
JasperReports Ultimate Guide (available from the JasperSoft eShop)
iReport Ultimate Guide (available from the JasperSoft eShop)

© 2001- TIBCO Software Inc. www.jaspersoft.com