Skip to content

Release v3.0.0

Latest

Choose a tag to compare

@hhdevr hhdevr released this 12 Sep 13:03
· 5 commits to main since this release

jasper-modular 3.0.0 is the next release after 2.0.1. Version 2.1.0 was never published, so everything it contained ships here. This is a major release: subreport parameter names change, and templates are now checked against your classes at build time. See Migrating from 2.0.x before upgrading.

Highlights

  • Repeating subreports from lists of modules. A List<T> field, where T is a @JasperSubreport module, renders one subreport instance per element. Every element brings its own compiled template, so one list can hold subclasses of a module with different templates. In 2.0.1 this was not supported.
  • Empty modules are skipped. A module whose isEmpty() returns true is skipped entirely — no parameters, no blank space. Empty and null elements are dropped from subreport lists.
  • Collections of simple values. List<String>, numbers, dates and enums get a dataset with a single _THIS field — the element itself — and a generated component. Previously the processor turned JDK types into nonsense fields such as bytes or empty.
  • Templates are checked at build time. The build fails when a template still declares a generated parameter or dataset that no field produces, or declares a parameter with a class that differs from its field. The error message says what to rename or delete.

⚠️ Breaking changes

  • Subreport parameter names come from the field. A field items produces itemsReport and itemsMapParameter; a list of modules in a field items produces itemsDataSource with the dataset itemsDataset. In 2.0.x the prefix was the prefix attribute or the module's simple class name. Rename the old parameters and their $P{...} references in your templates — the build lists which ones.
  • prefix is removed from @JasperSubreport.
  • Bean collections default to TABLE. A collection field without @JasperCollection now generates a table with column headers instead of a list. Components already in your templates are not changed; add @JasperCollection(type = CollectionComponentType.LIST) to keep generating lists.
  • SubreportModule.getOrder() and isStartNewPage() are removed. They never affected rendering; control order and page breaks in the template.
  • New compile errors. Besides the template check above, the build now fails when:
    • a @JasperModularReport class does not extend ModularReport, or a @JasperSubreport class does not extend SubreportModule;
    • a class carries both annotations, or the annotation is placed on a record, enum or interface;
    • two classes use the same templatePath;
    • two fields resolve to the same subreport parameter name;
    • a collection element is a record, or a collection of modules uses an element type without @JasperSubreport.

Improvements and fixes

  • Inheritance. Templates are generated only for classes that carry the annotation themselves. A subclass without its own annotation renders with the template of its nearest annotated ancestor, and a field declared with a base module type renders each instance with that instance's own template.
  • Template paths work with or without a leading / and share one cache entry. The startup precompiler resolves paths with the same rule as the runtime and compiles each template once, even when subclasses inherit it.
  • Dataset fields follow JavaBeans rules. Names come from the accessors, and the field class comes from the getter chosen by JavaBeans priority. Interface element types get their fields from their getters. Static fields without an accessor are skipped.
  • Clear warnings instead of silent gaps. A raw List, List<?> or an element type without readable properties produces a warning that points at the field. If the processor cannot find an existing template, it now warns before generating a blank skeleton — it looks in the compiled-classes output first, then on its own classpath.
  • No blank space for empty collections. Generated list/table components and subreport lists float and set removeLineWhenBlank.
  • Runtime: synthetic fields (for example JaCoCo's $jacocoData) no longer leak into the parameter map; wildcard element types are resolved the same way as in the processor; the template cache is cleared on every startup, so spring-boot-devtools restarts pick up edited JRXML. Static fields are still passed as parameters by design — use @JasperIgnore to exclude one.
  • Processor stability: type-variable fields no longer break generation.

Compatibility

  • Java 17+.
  • Spring Boot 3.3+ or 4.x for the starter (autoconfiguration and precompiler); the core does not depend on Spring.
  • JasperReports 6.x or 7.x in provided scope — bring your own engine version. Tested with 6.21.5 and 7.0.6. JRXML files are not interchangeable between 6.x and 7.x, so keep templates for the engine you run; the processor writes the dialect of the JasperReports version on its path.

Installation

<dependency>
    <groupId>io.github.hhdevr</groupId>
    <artifactId>jasper-modular-starter</artifactId>
    <version>3.0.0</version>
</dependency>

Add io.github.hhdevr:jasper-modular-processor:3.0.0 to annotationProcessorPaths together with your JasperReports version — see the README. A complete example lives in jasper-modular-sample.