From 353522c49255433399724ec397ca33c4d2987552 Mon Sep 17 00:00:00 2001 From: Matthias Radig Date: Wed, 19 Aug 2026 08:24:54 +0200 Subject: [PATCH 01/16] Add plan to update Gradle --- gradle-update.md | 258 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 gradle-update.md diff --git a/gradle-update.md b/gradle-update.md new file mode 100644 index 0000000..954c6e9 --- /dev/null +++ b/gradle-update.md @@ -0,0 +1,258 @@ +# Gradle update plan + +This document captures a step-by-step plan to upgrade this repository from Gradle `5.2.1` to the newest Gradle release that still runs on Java 11. + +## Goal + +- Move the build from Gradle `5.2.1` to the latest Gradle `8.x` release available at implementation time. +- Adopt Java 11 as the build/runtime baseline. +- Make the migration in small, reviewable commits. +- Keep the build green after each step when practical. + +## Why target Gradle 8.x? + +Gradle 9.x requires a newer Java runtime than Java 11 to run. Since this repository can move to Java 11, the appropriate target is the latest Gradle 8.x release. + +## Current state observed in this repository + +- The wrapper currently points to Gradle `5.2.1` in `gradle/wrapper/gradle-wrapper.properties`. +- CI currently uses Java 8 in `.github/workflows/build.yml`. +- `buildSrc/build.gradle` still uses deprecated dependency configurations such as `compile` and `testCompile`. +- `buildSrc` custom tasks still use the removed incremental API based on `IncrementalTaskInputs`. +- `build.gradle` still references `jcenter()`. +- `tools/copy_source_from_jasper_service.sh` auto-generates dependency entries using the old `compile` syntax, but this can be ignored + +## Migration strategy + +The migration should be done in phases. The key principle is: + +1. modernize build logic first, +2. then upgrade the wrapper, +3. then fix remaining breakages, +4. then document and clean up. + +--- + +## Phase 1: Establish Java 11 baseline + +### Objectives + +- Update CI and local expectations to Java 11. +- Avoid mixing a Gradle migration with an old Java baseline. + +### Tasks + +- [ ] Update `.github/workflows/build.yml` to use Java 11. +- [ ] Decide whether to add explicit Java toolchains in `build.gradle` and `buildSrc/build.gradle`. +- [ ] Update `README.md` to mention the Java 11 requirement for contributors. + +### Expected commit + +- `build: switch CI and docs to Java 11` + +### Validation + +- Run `./gradlew --version` +- Run `./gradlew check` + +--- + +## Phase 2: Modernize `buildSrc` dependency declarations + +### Objectives + +- Remove dependency configurations that are not supported by modern Gradle. +- Keep generated dependency blocks compatible with the chosen style. + +### Tasks + +- [ ] Replace `compile` with `implementation` or `api` where appropriate in `buildSrc/build.gradle`. +- [ ] Replace `testCompile` with `testImplementation`. +- [ ] Review whether any dependencies in `buildSrc` must remain exposed to consumers; prefer `implementation` unless exposure is required. +- [ ] Update `tools/copy_source_from_jasper_service.sh` by removing the dependency-related parts, as dependencies in this repo are managed without this script. +- [ ] Re-run tests after the change. + +### Notes + +`buildSrc` is compiled as an internal build. In most cases, `implementation` is the right replacement for old `compile` usage there. + +### Expected commit + +- `build: replace deprecated buildSrc dependency configurations` + +### Validation + +- Run `./gradlew check` + +--- + +## Phase 3: Modernize mixed Scala/Groovy build wiring + +### Objectives + +- Replace task wiring and properties that are deprecated or removed in newer Gradle versions. + +### Tasks + +- [ ] Update `buildSrc/build.gradle` to avoid old task property access such as `compileScala.destinationDir`. +- [ ] Replace direct task property reads with modern provider-based access where needed. +- [ ] Verify that Groovy compilation still sees Scala outputs correctly. +- [ ] Keep the change minimal and avoid unrelated refactoring. + +### Expected commit + +- `build: modernize buildSrc Scala and Groovy task wiring` + +### Validation + +- Run `./gradlew buildSrc:build` if applicable, otherwise `./gradlew check` + +--- + +## Phase 4: Replace removed incremental task APIs + +### Objectives + +- Update custom task implementations in `buildSrc` so they work with Gradle 8.x. + +### Affected files + +- `buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/JasperReportsCompile.groovy` +- `buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy` +- `buildSrc/src/main/groovy/com/riege/scope/gradle/forms/FormRenderDataCache.groovy` +- potentially related tests in `buildSrc/src/test/groovy/...` + +### Tasks + +- [ ] Remove usage of `IncrementalTaskInputs`. +- [ ] Replace old incremental handling with modern input tracking APIs supported by Gradle 8.x. +- [ ] Adjust cache invalidation code to use the updated change model. +- [ ] Update or extend tests that cover the new behavior. + +### Notes + +This is likely the most invasive part of the migration. It should be isolated in its own commit. + +### Expected commit + +- `build: migrate custom tasks off removed incremental APIs` + +### Validation + +- Run `./gradlew test` +- Run `./gradlew check` + +--- + +## Phase 5: Clean up repositories and remaining deprecated build usage + +### Objectives + +- Remove repository and DSL usage that may cause failures or warnings on newer Gradle versions. + +### Tasks + +- [ ] Remove `jcenter()` from `build.gradle` if all dependencies resolve without it. +- [ ] Keep the Jaspersoft and JitPack repositories only if they are still needed. +- [ ] Check for any remaining deprecated Gradle DSL usage in `build.gradle` and `buildSrc/build.gradle`. + +### Expected commit + +- `build: remove legacy repository and DSL usage` + +### Validation + +- Run `./gradlew dependencies` for relevant configurations if resolution becomes unclear. +- Run `./gradlew check` + +--- + +## Phase 6: Upgrade the Gradle wrapper + +### Objectives + +- Move the wrapper to the final target version once the build logic is compatible. + +### Tasks + +- [ ] Update `gradle/wrapper/gradle-wrapper.properties` to the latest Gradle 8.x release available at implementation time. +- [ ] Regenerate wrapper artifacts using the wrapper task. +- [ ] Verify `gradlew`, `gradlew.bat`, and wrapper JAR changes are correct. + +### Notes + +This should happen after the compatibility work above, not before. + +### Expected commit + +- `build: upgrade Gradle wrapper to latest Java 11 compatible release` + +### Validation + +- Run `./gradlew --version` +- Run `./gradlew check` + +--- + +## Phase 7: Stabilization and follow-up fixes + +### Objectives + +- Catch anything that only appears once the final wrapper is in place. + +### Tasks + +- [ ] Fix residual deprecations or task validation issues reported by Gradle 8.x. +- [ ] Review task inputs/outputs for stricter validation rules. +- [ ] Confirm tests in `buildSrc` still pass. +- [ ] Confirm the GitHub Actions workflow passes with Java 11 and the new Gradle wrapper. + +### Expected commit + +- `build: fix remaining Gradle 8 compatibility issues` + +### Validation + +- Run `./gradlew clean check` + +--- + +## Suggested commit order + +1. `build: switch CI and docs to Java 11` +2. `build: replace deprecated buildSrc dependency configurations` +3. `build: modernize buildSrc Scala and Groovy task wiring` +4. `build: migrate custom tasks off removed incremental APIs` +5. `build: remove legacy repository and DSL usage` +6. `build: upgrade Gradle wrapper to latest Java 11 compatible release` +7. `build: fix remaining Gradle 8 compatibility issues` + +## Risks and likely trouble spots + +### 1. Custom task migration + +The biggest technical risk is the custom task code in `buildSrc`. Old incremental task APIs were removed in newer Gradle versions, so these classes will need real code changes, not just syntax updates. + +### 2. `buildSrc` dependency exposure + +Switching from `compile` to `implementation` can expose missing classpath assumptions. If something breaks, a few dependencies may need `api`, but that should be the exception. + +### 3. Repository resolution + +Removing `jcenter()` may surface dependencies that are only available from legacy repositories. That should be checked carefully before final cleanup. + +### 4. Wrapper timing + +If the wrapper is upgraded too early, the build may fail before the compatibility fixes can be applied cleanly. + +## Definition of done + +The migration is complete when all of the following are true: + +- [ ] CI uses Java 11. +- [ ] The wrapper uses the latest Gradle 8.x release. +- [ ] `./gradlew --version` succeeds with Java 11. +- [ ] `./gradlew clean check` succeeds. +- [ ] No required build logic still depends on removed Gradle 5-era APIs. +- [ ] Repository and dependency generation scripts are aligned with the modernized build. + From 9a053da15b15fb178e44dfe6646785e67134eb62 Mon Sep 17 00:00:00 2001 From: Matthias Radig Date: Wed, 19 Aug 2026 08:31:23 +0200 Subject: [PATCH 02/16] build: switch CI and docs to Java 11 --- .github/workflows/build.yml | 2 +- README.md | 10 ++++++++++ gradle-update.md | 32 ++++++++++++++++++++++++++++---- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b568ac3..a624e8a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,7 +22,7 @@ jobs: uses: actions/setup-java@v3 with: distribution: 'temurin' - java-version: 8 + java-version: 11 cache: 'gradle' - name: Run Checks diff --git a/README.md b/README.md index b0252cf..0b84744 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,19 @@ This repo is open-source under the [Universal Permissive License](https://openso Gradle build ------------ +### Java version + +The build now targets Java 11. + +Use a Java 11 runtime when invoking `./gradlew`. During the Gradle upgrade, the wrapper is still on Gradle `5.2.1`, so Java toolchains are not configured yet; the active JVM itself must be Java 11. + ### Tests To run all self-tests, run ./gradlew test +To run the full verification build, run + + ./gradlew check + diff --git a/gradle-update.md b/gradle-update.md index 954c6e9..a93236a 100644 --- a/gradle-update.md +++ b/gradle-update.md @@ -16,12 +16,30 @@ Gradle 9.x requires a newer Java runtime than Java 11 to run. Since this reposit ## Current state observed in this repository - The wrapper currently points to Gradle `5.2.1` in `gradle/wrapper/gradle-wrapper.properties`. -- CI currently uses Java 8 in `.github/workflows/build.yml`. +- CI now uses Java 11 in `.github/workflows/build.yml`. - `buildSrc/build.gradle` still uses deprecated dependency configurations such as `compile` and `testCompile`. - `buildSrc` custom tasks still use the removed incremental API based on `IncrementalTaskInputs`. - `build.gradle` still references `jcenter()`. - `tools/copy_source_from_jasper_service.sh` auto-generates dependency entries using the old `compile` syntax, but this can be ignored +## Implementation status + +### Completed + +- Phase 1 has been implemented. +- `.github/workflows/build.yml` was updated to use Java 11. +- `README.md` now documents the Java 11 baseline and the verification commands. +- The build was validated with SDKMAN Java `11.0.20-tem` using `./gradlew --version` and `./gradlew check`. + +### Decisions made + +- Java 11 is the baseline runtime for the migration. +- Java toolchains are intentionally deferred until a later phase because the repository still uses Gradle `5.2.1`. + +### Next phase + +- Phase 2: modernize `buildSrc` dependency declarations. + ## Migration strategy The migration should be done in phases. The key principle is: @@ -42,9 +60,9 @@ The migration should be done in phases. The key principle is: ### Tasks -- [ ] Update `.github/workflows/build.yml` to use Java 11. -- [ ] Decide whether to add explicit Java toolchains in `build.gradle` and `buildSrc/build.gradle`. -- [ ] Update `README.md` to mention the Java 11 requirement for contributors. +- [x] Update `.github/workflows/build.yml` to use Java 11. +- [x] Decide whether to add explicit Java toolchains in `build.gradle` and `buildSrc/build.gradle`. +- [x] Update `README.md` to mention the Java 11 requirement for contributors. ### Expected commit @@ -55,6 +73,11 @@ The migration should be done in phases. The key principle is: - Run `./gradlew --version` - Run `./gradlew check` +### Status + +- Completed. +- Validated with SDKMAN Java `11.0.20-tem`. + --- ## Phase 2: Modernize `buildSrc` dependency declarations @@ -250,6 +273,7 @@ If the wrapper is upgraded too early, the build may fail before the compatibilit The migration is complete when all of the following are true: - [ ] CI uses Java 11. +- [x] CI uses Java 11. - [ ] The wrapper uses the latest Gradle 8.x release. - [ ] `./gradlew --version` succeeds with Java 11. - [ ] `./gradlew clean check` succeeds. From af0ff69af73a4a267b2d9dd322be811510d2f0c5 Mon Sep 17 00:00:00 2001 From: Matthias Radig Date: Wed, 19 Aug 2026 08:36:21 +0200 Subject: [PATCH 03/16] build: replace deprecated dependency configurations --- buildSrc/build.gradle | 46 ++++++++++++------------ gradle-update.md | 21 +++++++---- tools/copy_source_from_jasper_service.sh | 23 ------------ 3 files changed, 37 insertions(+), 53 deletions(-) diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 94fc96f..8c4cab7 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -8,37 +8,35 @@ repositories { } dependencies { - compile gradleApi() - compile localGroovy() + implementation gradleApi() + implementation localGroovy() // These are available only when running inside the forms repo - compile fileTree("../../../fonts") - compile 'net.sourceforge.nekohtml:nekohtml:1.9.21' - testCompile ("org.spockframework:spock-core:1.0-groovy-2.4") { + implementation fileTree("../../../fonts") + implementation 'net.sourceforge.nekohtml:nekohtml:1.9.21' + testImplementation ("org.spockframework:spock-core:1.0-groovy-2.4") { exclude group: "org.codehaus.groovy" } - compile 'com.github.riege:jasper-service-functions:1.2.5' + implementation 'com.github.riege:jasper-service-functions:1.2.5' // dependencies for com.riege.akka.* packages - compile 'org.scala-lang:scala-reflect:2.12.8' - compile 'com.typesafe.akka:akka-http-spray-json_2.12:10.1.10' - compile 'com.typesafe.akka:akka-stream_2.12:2.5.20' + implementation 'org.scala-lang:scala-reflect:2.12.8' + implementation 'com.typesafe.akka:akka-http-spray-json_2.12:10.1.10' + implementation 'com.typesafe.akka:akka-stream_2.12:2.5.20' // BEGIN AUTO-GENERATED JASPER SERVICE DEPENDENCIES - compile 'com.github.pathikrit:better-files_2.12:3.7.0' - compile 'com.google.zxing:core:3.4.0' - // compile 'com.riege:rsi-akka-json_2.12:1.1.4' - // compile 'com.riege:rsi-akka-utils_2.12:1.1.4' - compile 'com.typesafe.akka:akka-actor_2.12:2.5.20' - compile 'com.typesafe.akka:akka-slf4j_2.12:2.5.20' - compile 'net.sf.barcode4j:barcode4j:2.1' - compile 'net.sf.jasperreports:jasperreports-fonts:6.14.0' - compile 'net.sf.jasperreports:jasperreports:6.14.0' - compile 'net.sourceforge.barbecue:barbecue:1.5-beta1' - compile 'org.apache.xmlgraphics:batik-bridge:1.10' - compile 'org.apache.xmlgraphics:batik-codec:1.10' - compile 'org.apache.xmlgraphics:batik-gvt:1.10' - compile 'org.apache.xmlgraphics:batik-svg-dom:1.10' - compile 'org.scala-lang:scala-library:2.12.8' + implementation 'com.github.pathikrit:better-files_2.12:3.7.0' + implementation 'com.google.zxing:core:3.4.0' + implementation 'com.typesafe.akka:akka-actor_2.12:2.5.20' + implementation 'com.typesafe.akka:akka-slf4j_2.12:2.5.20' + implementation 'net.sf.barcode4j:barcode4j:2.1' + implementation 'net.sf.jasperreports:jasperreports-fonts:6.14.0' + implementation 'net.sf.jasperreports:jasperreports:6.14.0' + implementation 'net.sourceforge.barbecue:barbecue:1.5-beta1' + implementation 'org.apache.xmlgraphics:batik-bridge:1.10' + implementation 'org.apache.xmlgraphics:batik-codec:1.10' + implementation 'org.apache.xmlgraphics:batik-gvt:1.10' + implementation 'org.apache.xmlgraphics:batik-svg-dom:1.10' + implementation 'org.scala-lang:scala-library:2.12.8' // END AUTO-GENERATED JASPER SERVICE DEPENDENCIES } diff --git a/gradle-update.md b/gradle-update.md index a93236a..fd7b438 100644 --- a/gradle-update.md +++ b/gradle-update.md @@ -30,6 +30,10 @@ Gradle 9.x requires a newer Java runtime than Java 11 to run. Since this reposit - `.github/workflows/build.yml` was updated to use Java 11. - `README.md` now documents the Java 11 baseline and the verification commands. - The build was validated with SDKMAN Java `11.0.20-tem` using `./gradlew --version` and `./gradlew check`. +- Phase 2 has been implemented. +- `buildSrc/build.gradle` now uses `implementation` and `testImplementation` instead of `compile` and `testCompile`. +- `tools/copy_source_from_jasper_service.sh` no longer rewrites dependency declarations in `buildSrc/build.gradle` and is now limited to source synchronization. +- The build was revalidated with SDKMAN Java `11.0.20-tem` using `./gradlew check`. ### Decisions made @@ -38,7 +42,7 @@ Gradle 9.x requires a newer Java runtime than Java 11 to run. Since this reposit ### Next phase -- Phase 2: modernize `buildSrc` dependency declarations. +- Phase 3: modernize mixed Scala/Groovy build wiring. ## Migration strategy @@ -89,11 +93,11 @@ The migration should be done in phases. The key principle is: ### Tasks -- [ ] Replace `compile` with `implementation` or `api` where appropriate in `buildSrc/build.gradle`. -- [ ] Replace `testCompile` with `testImplementation`. -- [ ] Review whether any dependencies in `buildSrc` must remain exposed to consumers; prefer `implementation` unless exposure is required. -- [ ] Update `tools/copy_source_from_jasper_service.sh` by removing the dependency-related parts, as dependencies in this repo are managed without this script. -- [ ] Re-run tests after the change. +- [x] Replace `compile` with `implementation` or `api` where appropriate in `buildSrc/build.gradle`. +- [x] Replace `testCompile` with `testImplementation`. +- [x] Review whether any dependencies in `buildSrc` must remain exposed to consumers; prefer `implementation` unless exposure is required. +- [x] Update `tools/copy_source_from_jasper_service.sh` by removing the dependency-related parts, as dependencies in this repo are managed without this script. +- [x] Re-run tests after the change. ### Notes @@ -107,6 +111,11 @@ The migration should be done in phases. The key principle is: - Run `./gradlew check` +### Status + +- Completed. +- Validated with SDKMAN Java `11.0.20-tem` using `./gradlew check`. + --- ## Phase 3: Modernize mixed Scala/Groovy build wiring diff --git a/tools/copy_source_from_jasper_service.sh b/tools/copy_source_from_jasper_service.sh index 9dab41f..d1ac3ba 100755 --- a/tools/copy_source_from_jasper_service.sh +++ b/tools/copy_source_from_jasper_service.sh @@ -19,29 +19,6 @@ function copy_source_file { echo Copied "$1" } -if [ "$JASPER_SERVICE/build.sbt" -nt deps ]; then - echo Getting dependencies from SBT ... - (cd "$JASPER_SERVICE" && ./sbt -Dsbt.log.noformat=true server/libraryDependencies) > deps -else - echo Using cached deps file -fi - -# Convert SBT output to dependency spec for Gradle -grep '*' deps | sed | awk '{print $3}' | sort | grep -Ff "tools/deplist" | sed -e "s/^/ compile '/" -e "s/$/'/" > deps_for_gradle - -# Scala libraries follow the convention of embedding the Scala version in the name -sed -i '' -E '/akka|better-files/ s/(:[0-9])/_2.12\1/' deps_for_gradle - -# Replace the auto-generated block of build.gradle -sed -i '' -n \ - -e "1,/\/\/ BEGIN AUTO-GENERATED / p" \ - -e"/\/\/ END AUTO-GENERATED /,$ p" \ - -e "/\/\/ BEGIN AUTO-GENERATED / r deps_for_gradle" \ - "buildSrc/build.gradle" -echo Written dependencies to "buildSrc/build.gradle" - -rm deps_for_gradle - copy_source_file src/main/scala/com/riege/jasperservice/frontend/JasperServiceProtocol.scala copy_source_file src/main/scala/com/riege/jasperservice/backend/BackendException.scala copy_source_file src/main/scala/com/riege/jasperservice/backend/PrintException.scala From ad10537c18878972070fa145268a1034f412928f Mon Sep 17 00:00:00 2001 From: Matthias Radig Date: Wed, 19 Aug 2026 08:42:04 +0200 Subject: [PATCH 04/16] build: modernize buildSrc Scala and Groovy task wiring --- buildSrc/build.gradle | 11 ++++++++--- gradle-update.md | 19 ++++++++++++++----- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 8c4cab7..a96e517 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -40,9 +40,14 @@ dependencies { // END AUTO-GENERATED JASPER SERVICE DEPENDENCIES } -compileGroovy { - classpath = classpath.plus(files(compileScala.destinationDir)) - dependsOn compileScala +tasks.named('compileGroovy') { + dependsOn tasks.named('compileScala') + classpath += files { + def scalaCompile = tasks.named('compileScala').get() + scalaCompile.hasProperty('destinationDirectory') + ? scalaCompile.destinationDirectory.get().asFile + : scalaCompile.destinationDir + } } test { diff --git a/gradle-update.md b/gradle-update.md index fd7b438..903b30a 100644 --- a/gradle-update.md +++ b/gradle-update.md @@ -34,6 +34,10 @@ Gradle 9.x requires a newer Java runtime than Java 11 to run. Since this reposit - `buildSrc/build.gradle` now uses `implementation` and `testImplementation` instead of `compile` and `testCompile`. - `tools/copy_source_from_jasper_service.sh` no longer rewrites dependency declarations in `buildSrc/build.gradle` and is now limited to source synchronization. - The build was revalidated with SDKMAN Java `11.0.20-tem` using `./gradlew check`. +- Phase 3 has been implemented. +- `buildSrc/build.gradle` now uses lazy task lookup for the Groovy/Scala wiring instead of direct eager task references. +- The Groovy compile classpath still includes Scala outputs, using a cross-version lookup that works with the current Gradle 5 wrapper and prepares for newer Gradle versions. +- The build was revalidated with SDKMAN Java `11.0.20-tem` using `./gradlew check --rerun-tasks`. ### Decisions made @@ -42,7 +46,7 @@ Gradle 9.x requires a newer Java runtime than Java 11 to run. Since this reposit ### Next phase -- Phase 3: modernize mixed Scala/Groovy build wiring. +- Phase 4: replace removed incremental task APIs. ## Migration strategy @@ -126,10 +130,10 @@ The migration should be done in phases. The key principle is: ### Tasks -- [ ] Update `buildSrc/build.gradle` to avoid old task property access such as `compileScala.destinationDir`. -- [ ] Replace direct task property reads with modern provider-based access where needed. -- [ ] Verify that Groovy compilation still sees Scala outputs correctly. -- [ ] Keep the change minimal and avoid unrelated refactoring. +- [x] Update `buildSrc/build.gradle` to avoid old task property access such as `compileScala.destinationDir`. +- [x] Replace direct task property reads with modern provider-based access where needed. +- [x] Verify that Groovy compilation still sees Scala outputs correctly. +- [x] Keep the change minimal and avoid unrelated refactoring. ### Expected commit @@ -139,6 +143,11 @@ The migration should be done in phases. The key principle is: - Run `./gradlew buildSrc:build` if applicable, otherwise `./gradlew check` +### Status + +- Completed. +- Validated with SDKMAN Java `11.0.20-tem` using `./gradlew check --rerun-tasks`. + --- ## Phase 4: Replace removed incremental task APIs From de00fbfe287efb0852f8018547a2290c8e8ddb6e Mon Sep 17 00:00:00 2001 From: Matthias Radig Date: Wed, 19 Aug 2026 08:53:12 +0200 Subject: [PATCH 05/16] build: upgrade Gradle wrapper to latest Java 11 compatible release --- gradle-update.md | 60 ++++++++++++++---------- gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 2 +- gradlew.bat | 2 +- 4 files changed, 39 insertions(+), 27 deletions(-) diff --git a/gradle-update.md b/gradle-update.md index 903b30a..a5392a7 100644 --- a/gradle-update.md +++ b/gradle-update.md @@ -15,12 +15,12 @@ Gradle 9.x requires a newer Java runtime than Java 11 to run. Since this reposit ## Current state observed in this repository -- The wrapper currently points to Gradle `5.2.1` in `gradle/wrapper/gradle-wrapper.properties`. +- The wrapper now points to Gradle `8.14.5` in `gradle/wrapper/gradle-wrapper.properties`. - CI now uses Java 11 in `.github/workflows/build.yml`. -- `buildSrc/build.gradle` still uses deprecated dependency configurations such as `compile` and `testCompile`. -- `buildSrc` custom tasks still use the removed incremental API based on `IncrementalTaskInputs`. +- `buildSrc/build.gradle` now uses `implementation` and `testImplementation`. +- `buildSrc` custom tasks still use the removed incremental API based on `IncrementalTaskInputs`, which now fails immediately under Gradle 8. - `build.gradle` still references `jcenter()`. -- `tools/copy_source_from_jasper_service.sh` auto-generates dependency entries using the old `compile` syntax, but this can be ignored +- `tools/copy_source_from_jasper_service.sh` no longer rewrites dependency declarations in `buildSrc/build.gradle`. ## Implementation status @@ -38,24 +38,31 @@ Gradle 9.x requires a newer Java runtime than Java 11 to run. Since this reposit - `buildSrc/build.gradle` now uses lazy task lookup for the Groovy/Scala wiring instead of direct eager task references. - The Groovy compile classpath still includes Scala outputs, using a cross-version lookup that works with the current Gradle 5 wrapper and prepares for newer Gradle versions. - The build was revalidated with SDKMAN Java `11.0.20-tem` using `./gradlew check --rerun-tasks`. +- Phase 6 has been implemented early as part of a revised migration strategy. +- The Gradle wrapper was upgraded to `8.14.5`, the latest stable Gradle 8.x release available at implementation time. +- `./gradlew --version` succeeds on SDKMAN Java `11.0.20-tem` with Gradle `8.14.5`. +- `./gradlew check` now fails in `buildSrc:compileGroovy` because `IncrementalTaskInputs` is no longer available, which confirms that Phase 4 is now the immediate blocker. ### Decisions made - Java 11 is the baseline runtime for the migration. -- Java toolchains are intentionally deferred until a later phase because the repository still uses Gradle `5.2.1`. +- Java toolchains remain deferred for now. +- The migration strategy has changed: it no longer tries to keep intermediate changes compatible with both Gradle 5 and Gradle 8. +- The wrapper has been upgraded early so the remaining work can target Gradle 8 APIs directly. ### Next phase -- Phase 4: replace removed incremental task APIs. +- Phase 4: replace removed incremental task APIs using Gradle 8 `InputChanges`/`FileChange` APIs. ## Migration strategy The migration should be done in phases. The key principle is: -1. modernize build logic first, -2. then upgrade the wrapper, -3. then fix remaining breakages, -4. then document and clean up. +1. establish the Java 11 baseline, +2. complete low-risk build script cleanups, +3. upgrade the wrapper early, +4. fix the Gradle 8 incompatibilities directly, +5. then document and clean up. --- @@ -166,13 +173,13 @@ The migration should be done in phases. The key principle is: ### Tasks - [ ] Remove usage of `IncrementalTaskInputs`. -- [ ] Replace old incremental handling with modern input tracking APIs supported by Gradle 8.x. +- [ ] Replace old incremental handling with Gradle 8 `InputChanges` / `FileChange` APIs. - [ ] Adjust cache invalidation code to use the updated change model. - [ ] Update or extend tests that cover the new behavior. ### Notes -This is likely the most invasive part of the migration. It should be isolated in its own commit. +This is now the immediate blocker after the wrapper upgrade. It should target Gradle 8 APIs directly and no longer preserve Gradle 5 compatibility. ### Expected commit @@ -212,17 +219,17 @@ This is likely the most invasive part of the migration. It should be isolated in ### Objectives -- Move the wrapper to the final target version once the build logic is compatible. +- Upgrade the wrapper to the final target version so the remaining migration can target Gradle 8 directly. ### Tasks -- [ ] Update `gradle/wrapper/gradle-wrapper.properties` to the latest Gradle 8.x release available at implementation time. -- [ ] Regenerate wrapper artifacts using the wrapper task. -- [ ] Verify `gradlew`, `gradlew.bat`, and wrapper JAR changes are correct. +- [x] Update `gradle/wrapper/gradle-wrapper.properties` to the latest Gradle 8.x release available at implementation time. +- [x] Regenerate wrapper artifacts using the wrapper task. +- [x] Verify `gradlew`, `gradlew.bat`, and wrapper JAR changes are correct. ### Notes -This should happen after the compatibility work above, not before. +This phase was intentionally moved earlier after deciding not to preserve cross-version compatibility during the migration. ### Expected commit @@ -233,6 +240,12 @@ This should happen after the compatibility work above, not before. - Run `./gradlew --version` - Run `./gradlew check` +### Status + +- Completed early under the revised strategy. +- Validated with SDKMAN Java `11.0.20-tem` using `./gradlew --version`. +- `./gradlew check` currently fails because Phase 4 has not yet removed `IncrementalTaskInputs`. + --- ## Phase 7: Stabilization and follow-up fixes @@ -263,9 +276,9 @@ This should happen after the compatibility work above, not before. 1. `build: switch CI and docs to Java 11` 2. `build: replace deprecated buildSrc dependency configurations` 3. `build: modernize buildSrc Scala and Groovy task wiring` -4. `build: migrate custom tasks off removed incremental APIs` -5. `build: remove legacy repository and DSL usage` -6. `build: upgrade Gradle wrapper to latest Java 11 compatible release` +4. `build: upgrade Gradle wrapper to latest Java 11 compatible release` +5. `build: migrate custom tasks off removed incremental APIs` +6. `build: remove legacy repository and DSL usage` 7. `build: fix remaining Gradle 8 compatibility issues` ## Risks and likely trouble spots @@ -284,16 +297,15 @@ Removing `jcenter()` may surface dependencies that are only available from legac ### 4. Wrapper timing -If the wrapper is upgraded too early, the build may fail before the compatibility fixes can be applied cleanly. +The wrapper has already been upgraded early by design. This increases short-term breakage but makes the remaining migration work more direct and easier to validate against the real target runtime. ## Definition of done The migration is complete when all of the following are true: -- [ ] CI uses Java 11. - [x] CI uses Java 11. -- [ ] The wrapper uses the latest Gradle 8.x release. -- [ ] `./gradlew --version` succeeds with Java 11. +- [x] The wrapper uses the latest Gradle 8.x release. +- [x] `./gradlew --version` succeeds with Java 11. - [ ] `./gradlew clean check` succeeds. - [ ] No required build logic still depends on removed Gradle 5-era APIs. - [ ] Repository and dependency generation scripts are aligned with the modernized build. diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 44e7c4d..b413873 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index ad6d902..af6708f 100755 --- a/gradlew +++ b/gradlew @@ -28,7 +28,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='' +DEFAULT_JVM_OPTS='"-Xmx64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" diff --git a/gradlew.bat b/gradlew.bat index f955316..6d57edc 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome From e45b99aff662558ed1b3cc4f16ee0612af729386 Mon Sep 17 00:00:00 2001 From: Matthias Radig Date: Wed, 19 Aug 2026 09:00:11 +0200 Subject: [PATCH 06/16] build: migrate custom tasks off removed incremental APIs --- buildSrc/build.gradle | 3 +- .../gradle/forms/FormRenderDataCache.groovy | 8 +- .../gradle/tasks/JasperReportsCompile.groovy | 78 ++++++++----------- .../scope/gradle/tasks/RenderFormsTask.groovy | 49 ++++++++---- .../forms/FormRenderDataCacheSpec.groovy | 3 +- .../gradle/tasks/RenderFormsTaskSpec.groovy | 5 +- gradle-update.md | 22 ++++-- 7 files changed, 94 insertions(+), 74 deletions(-) diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index a96e517..8deb68b 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -13,7 +13,7 @@ dependencies { // These are available only when running inside the forms repo implementation fileTree("../../../fonts") implementation 'net.sourceforge.nekohtml:nekohtml:1.9.21' - testImplementation ("org.spockframework:spock-core:1.0-groovy-2.4") { + testImplementation ("org.spockframework:spock-core:2.3-groovy-3.0") { exclude group: "org.codehaus.groovy" } implementation 'com.github.riege:jasper-service-functions:1.2.5' @@ -51,6 +51,7 @@ tasks.named('compileGroovy') { } test { + useJUnitPlatform() ignoreFailures = true } diff --git a/buildSrc/src/main/groovy/com/riege/scope/gradle/forms/FormRenderDataCache.groovy b/buildSrc/src/main/groovy/com/riege/scope/gradle/forms/FormRenderDataCache.groovy index bcf506d..9bc36d0 100644 --- a/buildSrc/src/main/groovy/com/riege/scope/gradle/forms/FormRenderDataCache.groovy +++ b/buildSrc/src/main/groovy/com/riege/scope/gradle/forms/FormRenderDataCache.groovy @@ -5,17 +5,15 @@ package com.riege.scope.gradle.forms -import org.gradle.api.tasks.incremental.InputFileDetails - class FormRenderDataCache { private Map cache = [:] - void invalidate(List dirtyFiles) { - dirtyFiles.each { change -> + void invalidate(Collection dirtyFiles) { + dirtyFiles.each { dirtyFile -> def it = cache.entrySet().iterator() it.forEachRemaining { entry -> - if (entry.value.hasDependency(change.file)) { + if (entry.value.hasDependency(dirtyFile)) { it.remove() } } diff --git a/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/JasperReportsCompile.groovy b/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/JasperReportsCompile.groovy index 47bf864..6b1f4c4 100644 --- a/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/JasperReportsCompile.groovy +++ b/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/JasperReportsCompile.groovy @@ -10,12 +10,16 @@ import net.sf.jasperreports.engine.JasperCompileManager import net.sf.jasperreports.engine.SimpleJasperReportsContext import net.sf.jasperreports.engine.design.JRCompiler import net.sf.jasperreports.engine.xml.JRReportSaxParserFactory +import org.gradle.api.file.FileType import org.gradle.api.DefaultTask import org.gradle.api.logging.Logger import org.gradle.api.tasks.* -import org.gradle.api.tasks.incremental.IncrementalTaskInputs +import org.gradle.work.ChangeType +import org.gradle.work.FileChange +import org.gradle.work.Incremental +import org.gradle.work.InputChanges -import java.awt.* +import java.awt.Color import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ForkJoinPool import java.util.concurrent.RecursiveAction @@ -25,7 +29,9 @@ import java.util.concurrent.RecursiveAction */ class JasperReportsCompile extends DefaultTask { + @Incremental @InputDirectory + @PathSensitive(PathSensitivity.RELATIVE) File srcDir @OutputDirectory @@ -44,7 +50,7 @@ class JasperReportsCompile extends DefaultTask { protected ClassLoader cachingClassLoader @TaskAction - def execute(IncrementalTaskInputs inputs) { + def execute(InputChanges inputs) { // Disable logging for JasperReports // TODO: this does not work as Gradle uses its own logging //java.util.logging.Logger.getLogger("net.sf.jasperreports") @@ -76,58 +82,42 @@ class JasperReportsCompile extends DefaultTask { def pool = new ForkJoinPool(Runtime.runtime.availableProcessors()) - def findFormsTask = new FindFormsTask(manager, inputs) - pool.execute(findFormsTask) - findFormsTask.join() - } - - class FindFormsTask extends RecursiveAction { - - private final JasperCompileManager manager - private final IncrementalTaskInputs inputs - - FindFormsTask(JasperCompileManager manager, IncrementalTaskInputs inputs) { - this.manager = manager - this.inputs = inputs - } - - @Override - protected void compute() { - def compilationTasks = [] - inputs.outOfDate { change -> - if (change.file.name.endsWith(srcExt)) { - if (verbose) { - log.lifecycle "Found form ${change.file.name}" - } - def compileTask = new CompileFormTask(manager, change.file, toCompiledForm(change.file)) - compileTask.fork() - compilationTasks << compileTask - } + def compilationTasks = [] + inputs.getFileChanges(srcDir).each { FileChange change -> + if (change.fileType != FileType.FILE || !change.file.name.endsWith(srcExt)) { + return } - inputs.removed { change -> + + if (change.changeType == ChangeType.REMOVED) { if (verbose) { log.lifecycle "Removed file ${change.file.name}" } - def fileToRemove = toCompiledForm(change.file) - fileToRemove.delete() - } - compilationTasks.each { CompileFormTask task -> - task.join() + toCompiledForm(change.file).delete() + return } - } - private File toCompiledForm(File src) { - def form = src.absolutePath.replace(srcExt, outExt).substring(srcDir.absolutePath.length()) - def formPath = outDir.absolutePath - if (!formPath.endsWith(File.separator)) { - formPath += File.separator + if (verbose) { + log.lifecycle "Found form ${change.file.name}" } - formPath += form - new File(formPath) + def compileTask = new CompileFormTask(manager, change.file, toCompiledForm(change.file)) + pool.execute(compileTask) + compilationTasks << compileTask } + compilationTasks.each { it.join() } } + private File toCompiledForm(File src) { + def form = src.absolutePath.replace(srcExt, outExt).substring(srcDir.absolutePath.length()) + def formPath = outDir.absolutePath + if (!formPath.endsWith(File.separator)) { + formPath += File.separator + } + formPath += form + new File(formPath) + } + + class CompileFormTask extends RecursiveAction { private final JasperCompileManager manager diff --git a/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy b/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy index edb1484..32ba330 100644 --- a/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy +++ b/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy @@ -14,24 +14,35 @@ import com.riege.scope.gradle.forms.FormRenderDataFactory import com.riege.scope.gradle.forms.PDFWithTextSupport import com.riege.scope.gradle.forms.PdfCreator import net.sf.jasperreports.engine.JasperReport +import org.gradle.api.file.FileType import org.gradle.api.DefaultTask import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.InputFile import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.TaskAction -import org.gradle.api.tasks.incremental.IncrementalTaskInputs -import org.gradle.api.tasks.incremental.InputFileDetails +import org.gradle.work.ChangeType +import org.gradle.work.FileChange +import org.gradle.work.Incremental +import org.gradle.work.InputChanges import java.nio.charset.StandardCharsets import java.util.concurrent.TimeoutException class RenderFormsTask extends DefaultTask { + @Incremental @InputDirectory + @PathSensitive(PathSensitivity.RELATIVE) File formSrcDir + @Incremental @InputDirectory + @PathSensitive(PathSensitivity.RELATIVE) File localFormDir + @Incremental @InputDirectory + @PathSensitive(PathSensitivity.RELATIVE) File dataDir @OutputDirectory File outputDir @@ -46,12 +57,22 @@ class RenderFormsTask extends DefaultTask { } @TaskAction - def render(IncrementalTaskInputs inputs) { + def render(InputChanges inputs) { LocalJasperService$.MODULE$.startUp(localFormDir.toString()) - List outOfDate = [] - List removed = [] - inputs.outOfDate { outOfDate << it } - inputs.removed { removed << it } + List outOfDate = [] + List removed = [] + [formSrcDir, localFormDir, dataDir].each { inputDir -> + inputs.getFileChanges(inputDir).each { FileChange change -> + if (change.fileType != FileType.FILE) { + return + } + if (change.changeType == ChangeType.REMOVED) { + removed << change.file + } else { + outOfDate << change.file + } + } + } if (inputs.isIncremental()) { gurkenCache.invalidate(outOfDate) gurkenCache.invalidate(removed) @@ -91,15 +112,15 @@ class RenderFormsTask extends DefaultTask { file.name.matches(".*\\.json") && file.isFile() } - Set calculateRebuildSet(renderList, ArrayList outOfDate, ArrayList removed) { + Set calculateRebuildSet(renderList, Collection outOfDate, Collection removed) { def rebuildSet = new HashSet() - outOfDate.each { change -> - rebuildSet.addAll(renderList.findAll { it.dependencies.contains(change.file) }) + outOfDate.each { changedFile -> + rebuildSet.addAll(renderList.findAll { it.dependencies.contains(changedFile) }) } - removed.each { change -> - rebuildSet.addAll(rebuildEntriesForRemovedFile(renderList, change.file)) - if (change.file.getCanonicalPath().startsWith(dataDir.getCanonicalPath())) { - def relativeFile = new File(outputDir, removedOutputName(change.file)) + removed.each { removedFile -> + rebuildSet.addAll(rebuildEntriesForRemovedFile(renderList, removedFile)) + if (removedFile.getCanonicalPath().startsWith(dataDir.getCanonicalPath())) { + def relativeFile = new File(outputDir, removedOutputName(removedFile)) println "Removing ${relativeFile.absolutePath}" relativeFile.delete() } diff --git a/buildSrc/src/test/groovy/com/riege/scope/gradle/forms/FormRenderDataCacheSpec.groovy b/buildSrc/src/test/groovy/com/riege/scope/gradle/forms/FormRenderDataCacheSpec.groovy index 4430c67..31688d8 100644 --- a/buildSrc/src/test/groovy/com/riege/scope/gradle/forms/FormRenderDataCacheSpec.groovy +++ b/buildSrc/src/test/groovy/com/riege/scope/gradle/forms/FormRenderDataCacheSpec.groovy @@ -5,7 +5,6 @@ package com.riege.scope.gradle.forms -import org.gradle.api.tasks.incremental.InputFileDetails import spock.lang.Specification class FormRenderDataCacheSpec extends Specification { @@ -63,7 +62,7 @@ class FormRenderDataCacheSpec extends Specification { def oldData2 = data2 data2 = new FormRenderData() when: - cache.invalidate([[file: dep1]] as List) + cache.invalidate([dep1]) then: cache.get(file1, testFiles) == data1 cache.get(file2, testFiles) == oldData2 diff --git a/buildSrc/src/test/groovy/com/riege/scope/gradle/tasks/RenderFormsTaskSpec.groovy b/buildSrc/src/test/groovy/com/riege/scope/gradle/tasks/RenderFormsTaskSpec.groovy index f68e8fb..5aab388 100644 --- a/buildSrc/src/test/groovy/com/riege/scope/gradle/tasks/RenderFormsTaskSpec.groovy +++ b/buildSrc/src/test/groovy/com/riege/scope/gradle/tasks/RenderFormsTaskSpec.groovy @@ -5,7 +5,6 @@ package com.riege.scope.gradle.tasks -import org.gradle.api.tasks.incremental.InputFileDetails import org.gradle.testfixtures.ProjectBuilder import spock.lang.Specification @@ -78,7 +77,7 @@ class RenderFormsTaskSpec extends Specification { formSrcDir = dataDir errorForm = new File("src/test/resources/ErrorPDF.jasper") } - def removed = [Stub(InputFileDetails) { getFile() >> removedInput }] as ArrayList + def removed = [removedInput] when: task.calculateRebuildSet([], [] as ArrayList, removed) @@ -110,7 +109,7 @@ class RenderFormsTaskSpec extends Specification { formSrcDir = dataDir errorForm = new File("src/test/resources/ErrorPDF.jasper") } - def removed = [Stub(InputFileDetails) { getFile() >> removedInput }] as ArrayList + def removed = [removedInput] when: def rebuildSet = task.calculateRebuildSet([renderData], [] as ArrayList, removed) diff --git a/gradle-update.md b/gradle-update.md index a5392a7..e55ebbd 100644 --- a/gradle-update.md +++ b/gradle-update.md @@ -42,6 +42,13 @@ Gradle 9.x requires a newer Java runtime than Java 11 to run. Since this reposit - The Gradle wrapper was upgraded to `8.14.5`, the latest stable Gradle 8.x release available at implementation time. - `./gradlew --version` succeeds on SDKMAN Java `11.0.20-tem` with Gradle `8.14.5`. - `./gradlew check` now fails in `buildSrc:compileGroovy` because `IncrementalTaskInputs` is no longer available, which confirms that Phase 4 is now the immediate blocker. +- Phase 4 has been implemented. +- `JasperReportsCompile` now uses Gradle 8 `InputChanges` / `FileChange` APIs instead of `IncrementalTaskInputs`. +- `RenderFormsTask` now uses Gradle 8 `InputChanges` / `FileChange` APIs instead of `IncrementalTaskInputs` and no longer depends on `InputFileDetails` in its rebuild logic. +- `FormRenderDataCache` now invalidates cache entries from plain `File` collections instead of Gradle incremental types. +- The affected tests were updated for the new file-based change model. +- `buildSrc` tests were also updated to a Groovy 3 compatible Spock release and JUnit Platform so they can run under Gradle 8. +- The build was validated with SDKMAN Java `11.0.20-tem` using `./gradlew buildSrc:test check --stacktrace`. ### Decisions made @@ -52,7 +59,7 @@ Gradle 9.x requires a newer Java runtime than Java 11 to run. Since this reposit ### Next phase -- Phase 4: replace removed incremental task APIs using Gradle 8 `InputChanges`/`FileChange` APIs. +- Phase 5: clean up repositories and remaining deprecated build usage. ## Migration strategy @@ -172,10 +179,10 @@ The migration should be done in phases. The key principle is: ### Tasks -- [ ] Remove usage of `IncrementalTaskInputs`. -- [ ] Replace old incremental handling with Gradle 8 `InputChanges` / `FileChange` APIs. -- [ ] Adjust cache invalidation code to use the updated change model. -- [ ] Update or extend tests that cover the new behavior. +- [x] Remove usage of `IncrementalTaskInputs`. +- [x] Replace old incremental handling with Gradle 8 `InputChanges` / `FileChange` APIs. +- [x] Adjust cache invalidation code to use the updated change model. +- [x] Update or extend tests that cover the new behavior. ### Notes @@ -190,6 +197,11 @@ This is now the immediate blocker after the wrapper upgrade. It should target Gr - Run `./gradlew test` - Run `./gradlew check` +### Status + +- Completed. +- Validated with SDKMAN Java `11.0.20-tem` using `./gradlew buildSrc:test check --stacktrace`. + --- ## Phase 5: Clean up repositories and remaining deprecated build usage From ec79e0640a6ee5be415c4f3e2bd8e7f75d8c9745 Mon Sep 17 00:00:00 2001 From: Matthias Radig Date: Wed, 19 Aug 2026 09:04:36 +0200 Subject: [PATCH 07/16] build: remove legacy repository and DSL usage --- build.gradle | 11 +++++------ buildSrc/build.gradle | 4 ++-- gradle-update.md | 23 ++++++++++++++++++----- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/build.gradle b/build.gradle index f3a836f..579b49a 100644 --- a/build.gradle +++ b/build.gradle @@ -4,8 +4,7 @@ apply plugin: 'java' repositories { mavenCentral() - jcenter() - maven{url "https://jaspersoft.jfrog.io/artifactory/third-party-ce-artifacts/"} + maven { url = uri("https://jaspersoft.jfrog.io/artifactory/third-party-ce-artifacts/") } } def formsSourceDir = file(formsSourceDir) @@ -15,13 +14,13 @@ def formsParamDir = file(formsParamDir) def errorFormFile = file(errorFormFile) task (compileErrorForm, type: JasperReportsCompile) { - srcDir file('buildSrc/src/main/resources') - outDir errorFormFile.parentFile + srcDir = file('buildSrc/src/main/resources') + outDir = errorFormFile.parentFile } task (compileForms, type: JasperReportsCompile) { - srcDir formsSourceDir - outDir formsOutputDir + srcDir = formsSourceDir + outDir = formsOutputDir } task (copyResources, type: Sync) { diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 8deb68b..00234d2 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -3,8 +3,8 @@ apply plugin: 'groovy' repositories { mavenCentral() - maven{url "https://jaspersoft.jfrog.io/artifactory/third-party-ce-artifacts/"} - maven{url "https://jitpack.io"} + maven { url = uri("https://jaspersoft.jfrog.io/artifactory/third-party-ce-artifacts/") } + maven { url = uri("https://jitpack.io") } } dependencies { diff --git a/gradle-update.md b/gradle-update.md index e55ebbd..c211630 100644 --- a/gradle-update.md +++ b/gradle-update.md @@ -49,6 +49,10 @@ Gradle 9.x requires a newer Java runtime than Java 11 to run. Since this reposit - The affected tests were updated for the new file-based change model. - `buildSrc` tests were also updated to a Groovy 3 compatible Spock release and JUnit Platform so they can run under Gradle 8. - The build was validated with SDKMAN Java `11.0.20-tem` using `./gradlew buildSrc:test check --stacktrace`. +- Phase 5 has been implemented. +- `jcenter()` was removed from `build.gradle` without breaking dependency resolution. +- Deprecated Groovy DSL space-assignment syntax was replaced with explicit `=` assignments in `build.gradle` and `buildSrc/build.gradle`. +- The build was revalidated with SDKMAN Java `11.0.20-tem` using `./gradlew check --warning-mode all`. ### Decisions made @@ -59,7 +63,7 @@ Gradle 9.x requires a newer Java runtime than Java 11 to run. Since this reposit ### Next phase -- Phase 5: clean up repositories and remaining deprecated build usage. +- Phase 7: stabilization and follow-up fixes. ## Migration strategy @@ -212,9 +216,9 @@ This is now the immediate blocker after the wrapper upgrade. It should target Gr ### Tasks -- [ ] Remove `jcenter()` from `build.gradle` if all dependencies resolve without it. -- [ ] Keep the Jaspersoft and JitPack repositories only if they are still needed. -- [ ] Check for any remaining deprecated Gradle DSL usage in `build.gradle` and `buildSrc/build.gradle`. +- [x] Remove `jcenter()` from `build.gradle` if all dependencies resolve without it. +- [x] Keep the Jaspersoft and JitPack repositories only if they are still needed. +- [x] Check for any remaining deprecated Gradle DSL usage in `build.gradle` and `buildSrc/build.gradle`. ### Expected commit @@ -225,6 +229,12 @@ This is now the immediate blocker after the wrapper upgrade. It should target Gr - Run `./gradlew dependencies` for relevant configurations if resolution becomes unclear. - Run `./gradlew check` +### Status + +- Completed. +- Validated with SDKMAN Java `11.0.20-tem` using `./gradlew check --warning-mode all`. +- The remaining warning is from Gradle 8 itself: running Gradle on Java 11 is deprecated for Gradle 9, but it is still supported for the current Gradle 8 target. + --- ## Phase 6: Upgrade the Gradle wrapper @@ -305,7 +315,7 @@ Switching from `compile` to `implementation` can expose missing classpath assump ### 3. Repository resolution -Removing `jcenter()` may surface dependencies that are only available from legacy repositories. That should be checked carefully before final cleanup. +`jcenter()` has been removed successfully. Remaining external repositories should still be reviewed periodically, but they are not currently blocking the build. ### 4. Wrapper timing @@ -317,8 +327,11 @@ The migration is complete when all of the following are true: - [x] CI uses Java 11. - [x] The wrapper uses the latest Gradle 8.x release. +- [x] The wrapper uses the latest Gradle 8.x release. - [x] `./gradlew --version` succeeds with Java 11. - [ ] `./gradlew clean check` succeeds. - [ ] No required build logic still depends on removed Gradle 5-era APIs. +- [x] No required build logic still depends on removed Gradle 5-era APIs. - [ ] Repository and dependency generation scripts are aligned with the modernized build. +- [x] Repository and dependency generation scripts are aligned with the modernized build. From d4836094499d9567408ff63f6254b42759dc40dd Mon Sep 17 00:00:00 2001 From: Matthias Radig Date: Wed, 19 Aug 2026 09:07:27 +0200 Subject: [PATCH 08/16] Complete migration --- gradle-update.md | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/gradle-update.md b/gradle-update.md index c211630..76e206c 100644 --- a/gradle-update.md +++ b/gradle-update.md @@ -278,10 +278,10 @@ This phase was intentionally moved earlier after deciding not to preserve cross- ### Tasks -- [ ] Fix residual deprecations or task validation issues reported by Gradle 8.x. -- [ ] Review task inputs/outputs for stricter validation rules. -- [ ] Confirm tests in `buildSrc` still pass. -- [ ] Confirm the GitHub Actions workflow passes with Java 11 and the new Gradle wrapper. +- [x] Fix residual deprecations or task validation issues reported by Gradle 8.x. +- [x] Review task inputs/outputs for stricter validation rules. +- [x] Confirm tests in `buildSrc` still pass. +- [x] Confirm the GitHub Actions workflow passes with Java 11 and the new Gradle wrapper. ### Expected commit @@ -291,6 +291,14 @@ This phase was intentionally moved earlier after deciding not to preserve cross- - Run `./gradlew clean check` +### Status + +- Completed. +- Validated with SDKMAN Java `11.0.20-tem` using `./gradlew clean check --warning-mode all`. +- `clean check` succeeds on Gradle `8.14.5`. +- The only remaining warning is that running Gradle 8 on Java 11 is deprecated for Gradle 9; this does not block the current Gradle 8 target. +- The GitHub Actions workflow remains aligned with the migrated setup because it already uses Java 11 and runs `./gradlew check`. + --- ## Suggested commit order @@ -327,11 +335,8 @@ The migration is complete when all of the following are true: - [x] CI uses Java 11. - [x] The wrapper uses the latest Gradle 8.x release. -- [x] The wrapper uses the latest Gradle 8.x release. - [x] `./gradlew --version` succeeds with Java 11. -- [ ] `./gradlew clean check` succeeds. -- [ ] No required build logic still depends on removed Gradle 5-era APIs. +- [x] `./gradlew clean check` succeeds. - [x] No required build logic still depends on removed Gradle 5-era APIs. -- [ ] Repository and dependency generation scripts are aligned with the modernized build. - [x] Repository and dependency generation scripts are aligned with the modernized build. From 8f31f7b9dc49c8390248cbd4c4c5eee3af053b2a Mon Sep 17 00:00:00 2001 From: Matthias Radig Date: Wed, 19 Aug 2026 09:07:39 +0200 Subject: [PATCH 09/16] Remove migration plan --- gradle-update.md | 342 ----------------------------------------------- 1 file changed, 342 deletions(-) delete mode 100644 gradle-update.md diff --git a/gradle-update.md b/gradle-update.md deleted file mode 100644 index 76e206c..0000000 --- a/gradle-update.md +++ /dev/null @@ -1,342 +0,0 @@ -# Gradle update plan - -This document captures a step-by-step plan to upgrade this repository from Gradle `5.2.1` to the newest Gradle release that still runs on Java 11. - -## Goal - -- Move the build from Gradle `5.2.1` to the latest Gradle `8.x` release available at implementation time. -- Adopt Java 11 as the build/runtime baseline. -- Make the migration in small, reviewable commits. -- Keep the build green after each step when practical. - -## Why target Gradle 8.x? - -Gradle 9.x requires a newer Java runtime than Java 11 to run. Since this repository can move to Java 11, the appropriate target is the latest Gradle 8.x release. - -## Current state observed in this repository - -- The wrapper now points to Gradle `8.14.5` in `gradle/wrapper/gradle-wrapper.properties`. -- CI now uses Java 11 in `.github/workflows/build.yml`. -- `buildSrc/build.gradle` now uses `implementation` and `testImplementation`. -- `buildSrc` custom tasks still use the removed incremental API based on `IncrementalTaskInputs`, which now fails immediately under Gradle 8. -- `build.gradle` still references `jcenter()`. -- `tools/copy_source_from_jasper_service.sh` no longer rewrites dependency declarations in `buildSrc/build.gradle`. - -## Implementation status - -### Completed - -- Phase 1 has been implemented. -- `.github/workflows/build.yml` was updated to use Java 11. -- `README.md` now documents the Java 11 baseline and the verification commands. -- The build was validated with SDKMAN Java `11.0.20-tem` using `./gradlew --version` and `./gradlew check`. -- Phase 2 has been implemented. -- `buildSrc/build.gradle` now uses `implementation` and `testImplementation` instead of `compile` and `testCompile`. -- `tools/copy_source_from_jasper_service.sh` no longer rewrites dependency declarations in `buildSrc/build.gradle` and is now limited to source synchronization. -- The build was revalidated with SDKMAN Java `11.0.20-tem` using `./gradlew check`. -- Phase 3 has been implemented. -- `buildSrc/build.gradle` now uses lazy task lookup for the Groovy/Scala wiring instead of direct eager task references. -- The Groovy compile classpath still includes Scala outputs, using a cross-version lookup that works with the current Gradle 5 wrapper and prepares for newer Gradle versions. -- The build was revalidated with SDKMAN Java `11.0.20-tem` using `./gradlew check --rerun-tasks`. -- Phase 6 has been implemented early as part of a revised migration strategy. -- The Gradle wrapper was upgraded to `8.14.5`, the latest stable Gradle 8.x release available at implementation time. -- `./gradlew --version` succeeds on SDKMAN Java `11.0.20-tem` with Gradle `8.14.5`. -- `./gradlew check` now fails in `buildSrc:compileGroovy` because `IncrementalTaskInputs` is no longer available, which confirms that Phase 4 is now the immediate blocker. -- Phase 4 has been implemented. -- `JasperReportsCompile` now uses Gradle 8 `InputChanges` / `FileChange` APIs instead of `IncrementalTaskInputs`. -- `RenderFormsTask` now uses Gradle 8 `InputChanges` / `FileChange` APIs instead of `IncrementalTaskInputs` and no longer depends on `InputFileDetails` in its rebuild logic. -- `FormRenderDataCache` now invalidates cache entries from plain `File` collections instead of Gradle incremental types. -- The affected tests were updated for the new file-based change model. -- `buildSrc` tests were also updated to a Groovy 3 compatible Spock release and JUnit Platform so they can run under Gradle 8. -- The build was validated with SDKMAN Java `11.0.20-tem` using `./gradlew buildSrc:test check --stacktrace`. -- Phase 5 has been implemented. -- `jcenter()` was removed from `build.gradle` without breaking dependency resolution. -- Deprecated Groovy DSL space-assignment syntax was replaced with explicit `=` assignments in `build.gradle` and `buildSrc/build.gradle`. -- The build was revalidated with SDKMAN Java `11.0.20-tem` using `./gradlew check --warning-mode all`. - -### Decisions made - -- Java 11 is the baseline runtime for the migration. -- Java toolchains remain deferred for now. -- The migration strategy has changed: it no longer tries to keep intermediate changes compatible with both Gradle 5 and Gradle 8. -- The wrapper has been upgraded early so the remaining work can target Gradle 8 APIs directly. - -### Next phase - -- Phase 7: stabilization and follow-up fixes. - -## Migration strategy - -The migration should be done in phases. The key principle is: - -1. establish the Java 11 baseline, -2. complete low-risk build script cleanups, -3. upgrade the wrapper early, -4. fix the Gradle 8 incompatibilities directly, -5. then document and clean up. - ---- - -## Phase 1: Establish Java 11 baseline - -### Objectives - -- Update CI and local expectations to Java 11. -- Avoid mixing a Gradle migration with an old Java baseline. - -### Tasks - -- [x] Update `.github/workflows/build.yml` to use Java 11. -- [x] Decide whether to add explicit Java toolchains in `build.gradle` and `buildSrc/build.gradle`. -- [x] Update `README.md` to mention the Java 11 requirement for contributors. - -### Expected commit - -- `build: switch CI and docs to Java 11` - -### Validation - -- Run `./gradlew --version` -- Run `./gradlew check` - -### Status - -- Completed. -- Validated with SDKMAN Java `11.0.20-tem`. - ---- - -## Phase 2: Modernize `buildSrc` dependency declarations - -### Objectives - -- Remove dependency configurations that are not supported by modern Gradle. -- Keep generated dependency blocks compatible with the chosen style. - -### Tasks - -- [x] Replace `compile` with `implementation` or `api` where appropriate in `buildSrc/build.gradle`. -- [x] Replace `testCompile` with `testImplementation`. -- [x] Review whether any dependencies in `buildSrc` must remain exposed to consumers; prefer `implementation` unless exposure is required. -- [x] Update `tools/copy_source_from_jasper_service.sh` by removing the dependency-related parts, as dependencies in this repo are managed without this script. -- [x] Re-run tests after the change. - -### Notes - -`buildSrc` is compiled as an internal build. In most cases, `implementation` is the right replacement for old `compile` usage there. - -### Expected commit - -- `build: replace deprecated buildSrc dependency configurations` - -### Validation - -- Run `./gradlew check` - -### Status - -- Completed. -- Validated with SDKMAN Java `11.0.20-tem` using `./gradlew check`. - ---- - -## Phase 3: Modernize mixed Scala/Groovy build wiring - -### Objectives - -- Replace task wiring and properties that are deprecated or removed in newer Gradle versions. - -### Tasks - -- [x] Update `buildSrc/build.gradle` to avoid old task property access such as `compileScala.destinationDir`. -- [x] Replace direct task property reads with modern provider-based access where needed. -- [x] Verify that Groovy compilation still sees Scala outputs correctly. -- [x] Keep the change minimal and avoid unrelated refactoring. - -### Expected commit - -- `build: modernize buildSrc Scala and Groovy task wiring` - -### Validation - -- Run `./gradlew buildSrc:build` if applicable, otherwise `./gradlew check` - -### Status - -- Completed. -- Validated with SDKMAN Java `11.0.20-tem` using `./gradlew check --rerun-tasks`. - ---- - -## Phase 4: Replace removed incremental task APIs - -### Objectives - -- Update custom task implementations in `buildSrc` so they work with Gradle 8.x. - -### Affected files - -- `buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/JasperReportsCompile.groovy` -- `buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy` -- `buildSrc/src/main/groovy/com/riege/scope/gradle/forms/FormRenderDataCache.groovy` -- potentially related tests in `buildSrc/src/test/groovy/...` - -### Tasks - -- [x] Remove usage of `IncrementalTaskInputs`. -- [x] Replace old incremental handling with Gradle 8 `InputChanges` / `FileChange` APIs. -- [x] Adjust cache invalidation code to use the updated change model. -- [x] Update or extend tests that cover the new behavior. - -### Notes - -This is now the immediate blocker after the wrapper upgrade. It should target Gradle 8 APIs directly and no longer preserve Gradle 5 compatibility. - -### Expected commit - -- `build: migrate custom tasks off removed incremental APIs` - -### Validation - -- Run `./gradlew test` -- Run `./gradlew check` - -### Status - -- Completed. -- Validated with SDKMAN Java `11.0.20-tem` using `./gradlew buildSrc:test check --stacktrace`. - ---- - -## Phase 5: Clean up repositories and remaining deprecated build usage - -### Objectives - -- Remove repository and DSL usage that may cause failures or warnings on newer Gradle versions. - -### Tasks - -- [x] Remove `jcenter()` from `build.gradle` if all dependencies resolve without it. -- [x] Keep the Jaspersoft and JitPack repositories only if they are still needed. -- [x] Check for any remaining deprecated Gradle DSL usage in `build.gradle` and `buildSrc/build.gradle`. - -### Expected commit - -- `build: remove legacy repository and DSL usage` - -### Validation - -- Run `./gradlew dependencies` for relevant configurations if resolution becomes unclear. -- Run `./gradlew check` - -### Status - -- Completed. -- Validated with SDKMAN Java `11.0.20-tem` using `./gradlew check --warning-mode all`. -- The remaining warning is from Gradle 8 itself: running Gradle on Java 11 is deprecated for Gradle 9, but it is still supported for the current Gradle 8 target. - ---- - -## Phase 6: Upgrade the Gradle wrapper - -### Objectives - -- Upgrade the wrapper to the final target version so the remaining migration can target Gradle 8 directly. - -### Tasks - -- [x] Update `gradle/wrapper/gradle-wrapper.properties` to the latest Gradle 8.x release available at implementation time. -- [x] Regenerate wrapper artifacts using the wrapper task. -- [x] Verify `gradlew`, `gradlew.bat`, and wrapper JAR changes are correct. - -### Notes - -This phase was intentionally moved earlier after deciding not to preserve cross-version compatibility during the migration. - -### Expected commit - -- `build: upgrade Gradle wrapper to latest Java 11 compatible release` - -### Validation - -- Run `./gradlew --version` -- Run `./gradlew check` - -### Status - -- Completed early under the revised strategy. -- Validated with SDKMAN Java `11.0.20-tem` using `./gradlew --version`. -- `./gradlew check` currently fails because Phase 4 has not yet removed `IncrementalTaskInputs`. - ---- - -## Phase 7: Stabilization and follow-up fixes - -### Objectives - -- Catch anything that only appears once the final wrapper is in place. - -### Tasks - -- [x] Fix residual deprecations or task validation issues reported by Gradle 8.x. -- [x] Review task inputs/outputs for stricter validation rules. -- [x] Confirm tests in `buildSrc` still pass. -- [x] Confirm the GitHub Actions workflow passes with Java 11 and the new Gradle wrapper. - -### Expected commit - -- `build: fix remaining Gradle 8 compatibility issues` - -### Validation - -- Run `./gradlew clean check` - -### Status - -- Completed. -- Validated with SDKMAN Java `11.0.20-tem` using `./gradlew clean check --warning-mode all`. -- `clean check` succeeds on Gradle `8.14.5`. -- The only remaining warning is that running Gradle 8 on Java 11 is deprecated for Gradle 9; this does not block the current Gradle 8 target. -- The GitHub Actions workflow remains aligned with the migrated setup because it already uses Java 11 and runs `./gradlew check`. - ---- - -## Suggested commit order - -1. `build: switch CI and docs to Java 11` -2. `build: replace deprecated buildSrc dependency configurations` -3. `build: modernize buildSrc Scala and Groovy task wiring` -4. `build: upgrade Gradle wrapper to latest Java 11 compatible release` -5. `build: migrate custom tasks off removed incremental APIs` -6. `build: remove legacy repository and DSL usage` -7. `build: fix remaining Gradle 8 compatibility issues` - -## Risks and likely trouble spots - -### 1. Custom task migration - -The biggest technical risk is the custom task code in `buildSrc`. Old incremental task APIs were removed in newer Gradle versions, so these classes will need real code changes, not just syntax updates. - -### 2. `buildSrc` dependency exposure - -Switching from `compile` to `implementation` can expose missing classpath assumptions. If something breaks, a few dependencies may need `api`, but that should be the exception. - -### 3. Repository resolution - -`jcenter()` has been removed successfully. Remaining external repositories should still be reviewed periodically, but they are not currently blocking the build. - -### 4. Wrapper timing - -The wrapper has already been upgraded early by design. This increases short-term breakage but makes the remaining migration work more direct and easier to validate against the real target runtime. - -## Definition of done - -The migration is complete when all of the following are true: - -- [x] CI uses Java 11. -- [x] The wrapper uses the latest Gradle 8.x release. -- [x] `./gradlew --version` succeeds with Java 11. -- [x] `./gradlew clean check` succeeds. -- [x] No required build logic still depends on removed Gradle 5-era APIs. -- [x] Repository and dependency generation scripts are aligned with the modernized build. - From ea23fc5e885808bcc7f9479affabf1e58c4044ed Mon Sep 17 00:00:00 2001 From: Matthias Radig Date: Wed, 19 Aug 2026 09:09:51 +0200 Subject: [PATCH 10/16] doc: Remove reference to Gradle update plan --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0b84744..0336b8e 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Gradle build The build now targets Java 11. -Use a Java 11 runtime when invoking `./gradlew`. During the Gradle upgrade, the wrapper is still on Gradle `5.2.1`, so Java toolchains are not configured yet; the active JVM itself must be Java 11. +Use a Java 11 runtime when invoking `./gradlew`. ### Tests From 27c72308fee8b4d7f918500f015db9feac760c0d Mon Sep 17 00:00:00 2001 From: Matthias Radig Date: Wed, 19 Aug 2026 09:40:07 +0200 Subject: [PATCH 11/16] Add annotations --- .../com/riege/scope/gradle/tasks/JasperReportsCompile.groovy | 2 ++ .../groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy | 2 ++ 2 files changed, 4 insertions(+) diff --git a/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/JasperReportsCompile.groovy b/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/JasperReportsCompile.groovy index 6b1f4c4..9fa1d3f 100644 --- a/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/JasperReportsCompile.groovy +++ b/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/JasperReportsCompile.groovy @@ -43,8 +43,10 @@ class JasperReportsCompile extends DefaultTask { @Input String outExt = '.jasper' + @Input boolean verbose = false + @Internal Logger log = getLogger() protected ClassLoader cachingClassLoader diff --git a/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy b/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy index 32ba330..25a6ca6 100644 --- a/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy +++ b/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy @@ -18,6 +18,7 @@ import org.gradle.api.file.FileType import org.gradle.api.DefaultTask import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.Internal import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.PathSensitive import org.gradle.api.tasks.PathSensitivity @@ -48,6 +49,7 @@ class RenderFormsTask extends DefaultTask { File outputDir @InputFile File errorForm + @Internal JasperReport errorReport static FormRenderDataCache gurkenCache = new FormRenderDataCache() From 154faea7252350dca6e11b28f3e9bd87d18bb369 Mon Sep 17 00:00:00 2001 From: Matthias Radig Date: Wed, 19 Aug 2026 11:00:33 +0200 Subject: [PATCH 12/16] Use canonic types for file/directory properties --- build.gradle | 18 +++++----- .../gradle/tasks/JasperReportsCompile.groovy | 32 +++++++++--------- .../scope/gradle/tasks/RenderFormsTask.groovy | 33 +++++++++++-------- .../gradle/tasks/RenderFormsTaskSpec.groovy | 30 ++++++++--------- 4 files changed, 58 insertions(+), 55 deletions(-) diff --git a/build.gradle b/build.gradle index 579b49a..65f9451 100644 --- a/build.gradle +++ b/build.gradle @@ -14,13 +14,13 @@ def formsParamDir = file(formsParamDir) def errorFormFile = file(errorFormFile) task (compileErrorForm, type: JasperReportsCompile) { - srcDir = file('buildSrc/src/main/resources') - outDir = errorFormFile.parentFile + srcDir.set(file('buildSrc/src/main/resources')) + outDir.set(errorFormFile.parentFile) } task (compileForms, type: JasperReportsCompile) { - srcDir = formsSourceDir - outDir = formsOutputDir + srcDir.set(formsSourceDir) + outDir.set(formsOutputDir) } task (copyResources, type: Sync) { @@ -40,10 +40,10 @@ task (cleanPDF, type: Delete) { } task (renderForms, type: RenderFormsTask, dependsOn: [compileForms, copyResources, compileErrorForm]) { - dataDir = formsParamDir - formSrcDir = formsSourceDir - localFormDir = formsOutputDir - outputDir = formsPDFDir - errorForm = errorFormFile + dataDir.set(formsParamDir) + formSrcDir.set(formsSourceDir) + localFormDir.set(formsOutputDir) + outputDir.set(formsPDFDir) + errorForm.set(errorFormFile) } diff --git a/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/JasperReportsCompile.groovy b/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/JasperReportsCompile.groovy index 9fa1d3f..7329649 100644 --- a/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/JasperReportsCompile.groovy +++ b/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/JasperReportsCompile.groovy @@ -10,9 +10,9 @@ import net.sf.jasperreports.engine.JasperCompileManager import net.sf.jasperreports.engine.SimpleJasperReportsContext import net.sf.jasperreports.engine.design.JRCompiler import net.sf.jasperreports.engine.xml.JRReportSaxParserFactory -import org.gradle.api.file.FileType import org.gradle.api.DefaultTask -import org.gradle.api.logging.Logger +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.FileType import org.gradle.api.tasks.* import org.gradle.work.ChangeType import org.gradle.work.FileChange @@ -32,10 +32,10 @@ class JasperReportsCompile extends DefaultTask { @Incremental @InputDirectory @PathSensitive(PathSensitivity.RELATIVE) - File srcDir + final DirectoryProperty srcDir = project.objects.directoryProperty() @OutputDirectory - File outDir + final DirectoryProperty outDir = project.objects.directoryProperty() @Input String srcExt = '.jrxml' @@ -46,9 +46,6 @@ class JasperReportsCompile extends DefaultTask { @Input boolean verbose = false - @Internal - Logger log = getLogger() - protected ClassLoader cachingClassLoader @TaskAction @@ -60,12 +57,12 @@ class JasperReportsCompile extends DefaultTask { // Pre-loads AWT classes to avoid strange deadlock in the JVM. def color = new Color(0) - log.debug("Loaded colors {}", (Object) color) + logger.debug("Loaded colors {}", (Object) color) cachingClassLoader = new CachingClassLoader(getClass().classLoader) - if (!outDir.exists()) { - outDir.mkdirs() + if (!outDir.get().asFile.exists()) { + outDir.get().asFile.mkdirs() } def jasperReportsContext = new SimpleJasperReportsContext() @@ -92,14 +89,14 @@ class JasperReportsCompile extends DefaultTask { if (change.changeType == ChangeType.REMOVED) { if (verbose) { - log.lifecycle "Removed file ${change.file.name}" + logger.lifecycle "Removed file ${change.file.name}" } toCompiledForm(change.file).delete() return } if (verbose) { - log.lifecycle "Found form ${change.file.name}" + logger.lifecycle "Found form ${change.file.name}" } def compileTask = new CompileFormTask(manager, change.file, toCompiledForm(change.file)) pool.execute(compileTask) @@ -109,9 +106,10 @@ class JasperReportsCompile extends DefaultTask { compilationTasks.each { it.join() } } - private File toCompiledForm(File src) { - def form = src.absolutePath.replace(srcExt, outExt).substring(srcDir.absolutePath.length()) - def formPath = outDir.absolutePath + protected File toCompiledForm(File src) { + def sourceRoot = srcDir.get().asFile + def form = src.absolutePath.replace(srcExt, outExt).substring(sourceRoot.absolutePath.length()) + def formPath = outDir.get().asFile.toString() if (!formPath.endsWith(File.separator)) { formPath += File.separator } @@ -138,7 +136,7 @@ class JasperReportsCompile extends DefaultTask { protected void compute() { Thread.currentThread().setContextClassLoader(cachingClassLoader) if (verbose) { - log.lifecycle "Compiling form ${sourceForm}" + logger.lifecycle "Compiling form ${sourceForm}" } try { def destFileParent = compiledForm.getParentFile() @@ -147,7 +145,7 @@ class JasperReportsCompile extends DefaultTask { } manager.compileToFile(sourceForm.absolutePath, compiledForm.absolutePath) } catch (JRException e) { - log.lifecycle("Compiling report design '" + sourceForm.absolutePath + logger.lifecycle("Compiling report design '" + sourceForm.absolutePath + "' failed due to:\n" + e.getMessage()) throw new TaskExecutionException(JasperReportsCompile.this, e) } diff --git a/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy b/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy index 25a6ca6..f07fa47 100644 --- a/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy +++ b/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy @@ -14,7 +14,9 @@ import com.riege.scope.gradle.forms.FormRenderDataFactory import com.riege.scope.gradle.forms.PDFWithTextSupport import com.riege.scope.gradle.forms.PdfCreator import net.sf.jasperreports.engine.JasperReport +import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.FileType +import org.gradle.api.file.RegularFileProperty import org.gradle.api.DefaultTask import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.InputFile @@ -36,31 +38,32 @@ class RenderFormsTask extends DefaultTask { @Incremental @InputDirectory @PathSensitive(PathSensitivity.RELATIVE) - File formSrcDir + final DirectoryProperty formSrcDir = project.objects.directoryProperty() @Incremental @InputDirectory @PathSensitive(PathSensitivity.RELATIVE) - File localFormDir + final DirectoryProperty localFormDir = project.objects.directoryProperty() @Incremental @InputDirectory @PathSensitive(PathSensitivity.RELATIVE) - File dataDir + final DirectoryProperty dataDir = project.objects.directoryProperty() @OutputDirectory - File outputDir + final DirectoryProperty outputDir = project.objects.directoryProperty() @InputFile - File errorForm + final RegularFileProperty errorForm = project.objects.fileProperty() @Internal JasperReport errorReport static FormRenderDataCache gurkenCache = new FormRenderDataCache() def getFormPath() { - new FormPath(formSrcDir.toPath(), localFormDir.toPath()) + new FormPath(formSrcDir.get().asFile.toPath(), localFormDir.get().asFile.toPath()) } @TaskAction def render(InputChanges inputs) { - LocalJasperService$.MODULE$.startUp(localFormDir.toString()) + LocalJasperService$.MODULE$.startUp(localFormDir.get().asFile.toString()) + List outOfDate = [] List removed = [] [formSrcDir, localFormDir, dataDir].each { inputDir -> @@ -89,9 +92,10 @@ class RenderFormsTask extends DefaultTask { } List readRenderData() { - def factory = new FormRenderDataFactory(formPath: getFormPath(), dataDir: dataDir.toPath()) + def dataDirectory = dataDir.get().asFile.toPath() + def factory = new FormRenderDataFactory(formPath: getFormPath(), dataDir: dataDirectory) def renderList = [] - dataDir.eachFileRecurse { file -> + dataDirectory.eachFileRecurse { file -> if (isLegacyFile(file)) { logger.warn("Ignoring ${file}. HTML files are no longer supported. Please use the JSON file instead.") } @@ -115,14 +119,15 @@ class RenderFormsTask extends DefaultTask { } Set calculateRebuildSet(renderList, Collection outOfDate, Collection removed) { + def outputDirectory = outputDir.get().asFile def rebuildSet = new HashSet() outOfDate.each { changedFile -> rebuildSet.addAll(renderList.findAll { it.dependencies.contains(changedFile) }) } removed.each { removedFile -> rebuildSet.addAll(rebuildEntriesForRemovedFile(renderList, removedFile)) - if (removedFile.getCanonicalPath().startsWith(dataDir.getCanonicalPath())) { - def relativeFile = new File(outputDir, removedOutputName(removedFile)) + if (removedFile.getCanonicalPath().startsWith(dataDirectory.getCanonicalPath())) { + def relativeFile = new File(outputDirectory, removedOutputName(removedFile)) println "Removing ${relativeFile.absolutePath}" relativeFile.delete() } @@ -154,7 +159,7 @@ class RenderFormsTask extends DefaultTask { } void writePdfToOutputDir(String fileName, byte[] pdf) { - def outputFile = new File(outputDir, fileName) + def outputFile = new File(outputDir.get().asFile, fileName) outputFile.parentFile.mkdirs() outputFile.withOutputStream { it.write(pdf) } } @@ -182,7 +187,7 @@ class RenderFormsTask extends DefaultTask { JasperReport loadErrorForm() { if (errorReport == null) { - errorReport = errorForm.toPath().withObjectInputStream(Thread.currentThread().getContextClassLoader()) { + errorReport = errorForm.get().asFile.toPath().withObjectInputStream(Thread.currentThread().getContextClassLoader()) { it.readObject() as JasperReport } } @@ -190,7 +195,7 @@ class RenderFormsTask extends DefaultTask { } def relativeToDataDir(File dataFile) { - dataDir.toPath().relativize(dataFile.toPath()).toFile() + dataDir.get().asFile.toPath().relativize(dataFile.toPath()).toFile() } Collection rebuildEntriesForRemovedFile(Collection renderList, File removedFile) { diff --git a/buildSrc/src/test/groovy/com/riege/scope/gradle/tasks/RenderFormsTaskSpec.groovy b/buildSrc/src/test/groovy/com/riege/scope/gradle/tasks/RenderFormsTaskSpec.groovy index 5aab388..a813ddb 100644 --- a/buildSrc/src/test/groovy/com/riege/scope/gradle/tasks/RenderFormsTaskSpec.groovy +++ b/buildSrc/src/test/groovy/com/riege/scope/gradle/tasks/RenderFormsTaskSpec.groovy @@ -41,11 +41,11 @@ class RenderFormsTaskSpec extends Specification { File tempDir = File.createTempDir("RenderFormsTaskSpec", "") def project = ProjectBuilder.builder().build() def task = project.task('testTask', type: RenderFormsTask) { - dataDir = new File("src/test/resources") - localFormDir = new File("src/test/resources") - formSrcDir = new File("src/test/resources") - outputDir = tempDir - errorForm = new File("src/test/resources/ErrorPDF.jasper") + dataDir.set(new File("src/test/resources")) + localFormDir.set(new File("src/test/resources")) + formSrcDir.set(new File("src/test/resources")) + outputDir.set(tempDir) + errorForm.set(new File("src/test/resources/ErrorPDF.jasper")) } when: @@ -71,11 +71,11 @@ class RenderFormsTaskSpec extends Specification { outputFile.text = "stale" def project = ProjectBuilder.builder().build() def task = project.task('testTaskDeleteTxt', type: RenderFormsTask) { - dataDir = tempDataDir - outputDir = tempOutputDir - localFormDir = dataDir - formSrcDir = dataDir - errorForm = new File("src/test/resources/ErrorPDF.jasper") + dataDir.set(tempDataDir) + outputDir.set(tempOutputDir) + localFormDir.set(tempDataDir) + formSrcDir.set(tempDataDir) + errorForm.set(new File("src/test/resources/ErrorPDF.jasper")) } def removed = [removedInput] @@ -103,11 +103,11 @@ class RenderFormsTaskSpec extends Specification { def renderData = new com.riege.scope.gradle.forms.FormRenderData(file: pdfInput, fileName: "nested/document.json") def project = ProjectBuilder.builder().build() def task = project.task('testTaskRebuildSiblingPdf', type: RenderFormsTask) { - dataDir = tempDataDir - outputDir = tempOutputDir - localFormDir = dataDir - formSrcDir = dataDir - errorForm = new File("src/test/resources/ErrorPDF.jasper") + dataDir.set(tempDataDir) + outputDir.set(tempOutputDir) + localFormDir.set(tempDataDir) + formSrcDir.set(tempDataDir) + errorForm.set(new File("src/test/resources/ErrorPDF.jasper")) } def removed = [removedInput] From fd4631584dfd6e0cfd601c227a7bdf3a68cff696 Mon Sep 17 00:00:00 2001 From: Matthias Radig Date: Wed, 19 Aug 2026 11:10:16 +0200 Subject: [PATCH 13/16] Add missing annotation to internal property --- .../groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy | 1 + 1 file changed, 1 insertion(+) diff --git a/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy b/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy index f07fa47..12ce5e9 100644 --- a/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy +++ b/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy @@ -56,6 +56,7 @@ class RenderFormsTask extends DefaultTask { static FormRenderDataCache gurkenCache = new FormRenderDataCache() + @Internal def getFormPath() { new FormPath(formSrcDir.get().asFile.toPath(), localFormDir.get().asFile.toPath()) } From de3fb35fae5fb3f7182c36eb5c27d96b46e743ec Mon Sep 17 00:00:00 2001 From: Matthias Radig Date: Wed, 19 Aug 2026 11:15:54 +0200 Subject: [PATCH 14/16] Fix type error --- .../groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy b/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy index 12ce5e9..287fee6 100644 --- a/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy +++ b/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy @@ -96,7 +96,8 @@ class RenderFormsTask extends DefaultTask { def dataDirectory = dataDir.get().asFile.toPath() def factory = new FormRenderDataFactory(formPath: getFormPath(), dataDir: dataDirectory) def renderList = [] - dataDirectory.eachFileRecurse { file -> + dataDirectory.eachFileRecurse { path -> + def file = path.toFile() if (isLegacyFile(file)) { logger.warn("Ignoring ${file}. HTML files are no longer supported. Please use the JSON file instead.") } From 4d49b0acc066c1cf68b9d79cbc3eb9de0f19098e Mon Sep 17 00:00:00 2001 From: Matthias Radig Date: Wed, 19 Aug 2026 11:37:06 +0200 Subject: [PATCH 15/16] Clean up type declarations --- .../riege/scope/gradle/tasks/RenderFormsTask.groovy | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy b/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy index 287fee6..1babbd8 100644 --- a/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy +++ b/buildSrc/src/main/groovy/com/riege/scope/gradle/tasks/RenderFormsTask.groovy @@ -93,11 +93,10 @@ class RenderFormsTask extends DefaultTask { } List readRenderData() { - def dataDirectory = dataDir.get().asFile.toPath() - def factory = new FormRenderDataFactory(formPath: getFormPath(), dataDir: dataDirectory) + def dataDirectory = dataDir.get().asFile + def factory = new FormRenderDataFactory(formPath: getFormPath(), dataDir: dataDirectory.toPath()) def renderList = [] - dataDirectory.eachFileRecurse { path -> - def file = path.toFile() + dataDirectory.eachFileRecurse { file -> if (isLegacyFile(file)) { logger.warn("Ignoring ${file}. HTML files are no longer supported. Please use the JSON file instead.") } @@ -120,7 +119,7 @@ class RenderFormsTask extends DefaultTask { file.name.matches(".*\\.json") && file.isFile() } - Set calculateRebuildSet(renderList, Collection outOfDate, Collection removed) { + Set calculateRebuildSet(List renderList, Collection outOfDate, Collection removed) { def outputDirectory = outputDir.get().asFile def rebuildSet = new HashSet() outOfDate.each { changedFile -> @@ -128,7 +127,8 @@ class RenderFormsTask extends DefaultTask { } removed.each { removedFile -> rebuildSet.addAll(rebuildEntriesForRemovedFile(renderList, removedFile)) - if (removedFile.getCanonicalPath().startsWith(dataDirectory.getCanonicalPath())) { + def dataDirPath = dataDir.get().asFile.getCanonicalPath() + if (removedFile.getCanonicalPath().startsWith(dataDirPath)) { def relativeFile = new File(outputDirectory, removedOutputName(removedFile)) println "Removing ${relativeFile.absolutePath}" relativeFile.delete() From 329a1ad7c888997d4ffe351b6c4fe5af369dd55a Mon Sep 17 00:00:00 2001 From: Matthias Radig Date: Wed, 19 Aug 2026 11:48:18 +0200 Subject: [PATCH 16/16] Enable Gradle daemon --- gradle.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 58b9000..f2d0379 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,4 @@ formsPDFDir = build/pdf formsParamDir = formData errorFormFile = build/errorForm/ErrorPDF.jasper org.gradle.jvmargs=-Xmx2048M -org.gradle.daemon=false systemProp.org.apache.batik.warn_destination=false