JasperReports
A Quarkus extension that lets you utilize JasperReports. JasperReports is an open source Java reporting tool that can write to a variety of targets, such as: screen, a printer, into PDF, HTML, Microsoft Excel, RTF, ODT, comma-separated values (CSV), XSL, or XML files.
Installation
If you want to use this extension, you need to add the io.quarkiverse.jasperreports:quarkus-jasperreports
extension first to your build file.
For instance, with Maven, add the following dependency to your POM file:
<dependency>
<groupId>io.quarkiverse.jasperreports</groupId>
<artifactId>quarkus-jasperreports</artifactId>
<version>1.0.3</version>
</dependency>
Compiling Reports
JasperReports advises against compiling .jrxml
reports on the fly. However, if necessary, this can only be done in JVM mode, as native mode does not support Java compilation due to the absence of a Java compiler and the required classes for compilation. The recommended best practice is to use precompiled .jasper
files.
This extension provides built-in functionality to assist with this. If you place your .jrxml
files in the quarkus.jasperreports.build.source
directory, they will be automatically compiled into .jasper
files in the quarkus.jasperreports.build.dest
directory. In DEV
mode, it will monitor changes in the .jrxml
files and recompile them, enhancing developer productivity and joy!
Database Datasource
When utilizing an Agroal Datasource to generate your report, ensure it is not within an active transaction. JasperReports employs threads for sub-reports and various features, and a connection cannot be passed across thread boundaries while in a transaction. Failing to do so will result in the following error: Enlisted connection used without active transaction
.
Caused by: java.sql.SQLException: Enlisted connection used without active transaction
2024-07-22T21:24:13.599110173Z at io.agroal.pool.ConnectionHandler.verifyEnlistment(ConnectionHandler.java:398)
2024-07-22T21:24:13.599149982Z at io.agroal.pool.wrapper.ConnectionWrapper.getMetaData(ConnectionWrapper.java:452)
2024-07-22T21:24:13.599212173Z at net.sf.jasperreports.engine.query.OracleProcedureCallHandler.isOracle(OracleProcedureCallHandler.java:72)
2024-07-22T21:24:13.599341106Z at net.sf.jasperreports.engine.query.JRJdbcQueryExecuter.isProcedureCall(JRJdbcQueryExecuter.java:566)
2024-07-22T21:24:13.599481640Z at net.sf.jasperreports.engine.query.JRJdbcQueryExecuter.createStatement(JRJdbcQueryExecuter.java:389)
In your service you must use @Transactional(Transactional.TxType.NOT_SUPPORTED) above the method that is filling your report.
|
@Inject
DataSource datasource;
@Transactional(Transactional.TxType.NOT_SUPPORTED)
public byte[] text() throws JRException, SQLException {
JasperPrint jasperPrint = null;
try (final Connection connection = datasource.getConnection()) {
params.put(JRParameter.REPORT_CONNECTION, connection);
jasperPrint = JRFiller.fill(DefaultJasperReportsContext.getInstance(), SimpleJasperReportSource.from(mainReport, null, new SimpleRepositoryResourceContext()), params);
}
final JRTextExporter exporter = new JRTextExporter();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
exporter.setExporterOutput(new SimpleWriterExporterOutput(outputStream));
exporter.exportReport();
return outputStream.toByteArray();
}
Read-Only Streaming Service
This extension offers an injectable JasperReports repository capable of managing all the resources required for a report, including referenced sub-reports. Just inject the ReadOnlyStreamingService
repository and use it with the fill manager to generate the report.
@Inject
ReadOnlyStreamingService jasperService;
public JasperPrint fill() throws JRException {
Map<String, Object> params = new HashMap<>();
return JasperFillManager.getInstance(jasperService.getContext()).fillFromRepo("MyReport.jasper", params);
}
Native Container
When building native images in Docker using the standard Quarkus Docker configuration files some additional features need to be installed to support fonts. Specifically font information is not included in Red Hat’s ubi-minimal images. To install it simply add these lines to your DockerFile.native
file:
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.9
######################### Set up environment for POI ##########################
RUN microdnf update && microdnf install freetype fontconfig && microdnf clean all
######################### Set up environment for POI ##########################
WORKDIR /work/
RUN chown 1001 /work \
&& chmod "g+rwX" /work \
&& chown 1001:root /work
# Shared objects to be dynamically loaded at runtime as needed,
COPY --chown=1001:root target/*.properties target/*.so /work/
COPY --chown=1001:root target/*-runner /work/application
# Permissions fix for Windows
RUN chmod "ugo+x" /work/application
EXPOSE 8080
USER 1001
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
Make sure .dockerignore does not exclude .so files!
|
Extension Configuration Reference
Configuration property fixed at build time - All other configuration properties are overridable at runtime
Configuration property |
Type |
Default |
---|---|---|
Enable building all report files. Environment variable: |
boolean |
|
The path where all source Environment variable: |
path |
|
The path where compiled reports are located next to compiled classes. Environment variable: |
path |
|