From f262a26ad7e4dfa19dce641ad7f5b0547927faa3 Mon Sep 17 00:00:00 2001 From: Flavio Soibelmann Glock Date: Fri, 27 Mar 2026 19:50:30 +0100 Subject: [PATCH 1/4] fix: improve Java 25+ Gradle compatibility check in Makefile More robust fix for #392: - Always clear gradle-8.* caches when Java 25+ is detected - Update all Gradle-dependent targets to use check-java-gradle - Include clean, deb, test-unit, test-gradle-*, and sbom-java targets - Better error messages when system gradle is not available - Only attempt wrapper update if properties show Gradle < 9 The fix now handles the case where `make clean` is run first (which was failing in the original report). Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- Makefile | 41 +++++++++++-------- .../org/perlonjava/core/Configuration.java | 2 +- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 7683a2ecd..61ab53494 100644 --- a/Makefile +++ b/Makefile @@ -11,21 +11,26 @@ else endif # Check Java/Gradle compatibility and fix if needed +# For Java 25+, we need Gradle 9.0+ - this will auto-fix wrapper and clear old caches check-java-gradle: - @test -f ./gradlew || gradle wrapper ifeq ($(OS),Windows_NT) - @echo "Checking Java/Gradle compatibility..." + @if not exist gradlew gradle wrapper --gradle-version=9.0 else @JAVA_MAJOR=$$(java -version 2>&1 | head -1 | sed -E 's/.*version "([0-9]+).*/\1/'); \ - GRADLE_VER=$$(grep distributionUrl gradle/wrapper/gradle-wrapper.properties | sed -E 's/.*gradle-([0-9]+)\..*/\1/'); \ - if [ "$$JAVA_MAJOR" -ge 25 ] && [ "$$GRADLE_VER" -lt 9 ]; then \ - echo ""; \ - echo "WARNING: Java $$JAVA_MAJOR detected but Gradle wrapper is version $$GRADLE_VER.x"; \ - echo "Java 25+ requires Gradle 9.0+. Updating wrapper..."; \ - echo ""; \ - rm -rf ~/.gradle/wrapper/dists/gradle-$$GRADLE_VER.*; \ - ./gradlew wrapper --gradle-version=9.0 2>/dev/null || gradle wrapper --gradle-version=9.0; \ - echo "Gradle wrapper updated to 9.0"; \ + if [ "$$JAVA_MAJOR" -ge 25 ]; then \ + echo "Java $$JAVA_MAJOR detected - ensuring Gradle 9.0+ compatibility..."; \ + rm -rf ~/.gradle/wrapper/dists/gradle-8.*; \ + if [ -f ./gradlew ]; then \ + CURRENT_VER=$$(grep distributionUrl gradle/wrapper/gradle-wrapper.properties 2>/dev/null | sed -E 's/.*gradle-([0-9]+)\..*/\1/'); \ + if [ "$$CURRENT_VER" -lt 9 ] 2>/dev/null; then \ + echo "Updating Gradle wrapper from $$CURRENT_VER.x to 9.0..."; \ + gradle wrapper --gradle-version=9.0 || { echo "Error: 'gradle' command not found. Please install Gradle 9.0+ or run: rm -rf ~/.gradle/wrapper/dists/gradle-8.*"; exit 1; }; \ + fi; \ + else \ + gradle wrapper --gradle-version=9.0 || { echo "Error: 'gradle' command not found. Please install Gradle."; exit 1; }; \ + fi; \ + else \ + test -f ./gradlew || gradle wrapper; \ fi endif @@ -52,7 +57,7 @@ test: test-unit # Fast unit tests only (from src/test/resources/unit/ directory) # Uses Gradle's testUnitParallel (same as default make build) -test-unit: wrapper +test-unit: check-java-gradle ifeq ($(OS),Windows_NT) gradlew.bat testUnitParallel --parallel else @@ -110,7 +115,7 @@ test-all: test-perl5 test-modules test-gradle: test-gradle-parallel # Fast unit tests via Gradle/JUnit -test-gradle-unit: wrapper +test-gradle-unit: check-java-gradle ifeq ($(OS),Windows_NT) gradlew.bat testUnit --rerun-tasks else @@ -118,7 +123,7 @@ else endif # All tests via Gradle/JUnit -test-gradle-all: wrapper +test-gradle-all: check-java-gradle ifeq ($(OS),Windows_NT) gradlew.bat testAll --rerun-tasks else @@ -126,7 +131,7 @@ else endif # Parallel unit tests via Gradle/JUnit (4 JVMs) -test-gradle-parallel: wrapper +test-gradle-parallel: check-java-gradle ifeq ($(OS),Windows_NT) gradlew.bat testUnitParallel --parallel --rerun-tasks else @@ -141,14 +146,14 @@ else mvn test -Pshard1 & mvn test -Pshard2 & mvn test -Pshard3 & mvn test -Pshard4 & wait endif -clean: wrapper +clean: check-java-gradle ifeq ($(OS),Windows_NT) gradlew.bat clean else ./gradlew clean endif -deb: wrapper +deb: check-java-gradle ifeq ($(OS),Windows_NT) gradlew.bat buildDeb else @@ -165,7 +170,7 @@ sbom: sbom-java sbom-perl @echo "Combined SBOM generated: build/reports/sbom.json" # Generate Java SBOM using CycloneDX Gradle plugin -sbom-java: wrapper +sbom-java: check-java-gradle ifeq ($(OS),Windows_NT) gradlew.bat cyclonedxBom else diff --git a/src/main/java/org/perlonjava/core/Configuration.java b/src/main/java/org/perlonjava/core/Configuration.java index 0975a3b6c..d453a980f 100644 --- a/src/main/java/org/perlonjava/core/Configuration.java +++ b/src/main/java/org/perlonjava/core/Configuration.java @@ -33,7 +33,7 @@ public final class Configuration { * Automatically populated by Gradle/Maven during build. * DO NOT EDIT MANUALLY - this value is replaced at build time. */ - public static final String gitCommitId = "149932a22"; + public static final String gitCommitId = "6a55c14f3"; /** * Git commit date of the build (ISO format: YYYY-MM-DD). From 2620e2748e99d9d2d1e9725ec2cda3800fd19d20 Mon Sep 17 00:00:00 2001 From: Flavio Soibelmann Glock Date: Fri, 27 Mar 2026 19:59:54 +0100 Subject: [PATCH 2/4] fix: properly compare Gradle versions and use 9.1.0 for Java 25+ - Update check-java-gradle to extract both major and minor version numbers - Properly compare versions to detect 9.0.x as insufficient for Java 25+ - Clear both gradle-8.* and gradle-9.0* cache directories - Use Gradle 9.1.0 (first version with full Java 25 support) - Update docs with official Gradle compatibility matrix Fixes #392 Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- Makefile | 25 ++++++++----------- docs/getting-started/installation.md | 11 +++++--- .../org/perlonjava/core/Configuration.java | 2 +- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 61ab53494..4a3ca6e22 100644 --- a/Makefile +++ b/Makefile @@ -11,26 +11,23 @@ else endif # Check Java/Gradle compatibility and fix if needed -# For Java 25+, we need Gradle 9.0+ - this will auto-fix wrapper and clear old caches +# For Java 25+, we need Gradle 9.1.0+ (see https://docs.gradle.org/current/userguide/compatibility.html) check-java-gradle: ifeq ($(OS),Windows_NT) - @if not exist gradlew gradle wrapper --gradle-version=9.0 + @if not exist gradlew gradle wrapper --gradle-version=9.1.0 else @JAVA_MAJOR=$$(java -version 2>&1 | head -1 | sed -E 's/.*version "([0-9]+).*/\1/'); \ if [ "$$JAVA_MAJOR" -ge 25 ]; then \ - echo "Java $$JAVA_MAJOR detected - ensuring Gradle 9.0+ compatibility..."; \ - rm -rf ~/.gradle/wrapper/dists/gradle-8.*; \ - if [ -f ./gradlew ]; then \ - CURRENT_VER=$$(grep distributionUrl gradle/wrapper/gradle-wrapper.properties 2>/dev/null | sed -E 's/.*gradle-([0-9]+)\..*/\1/'); \ - if [ "$$CURRENT_VER" -lt 9 ] 2>/dev/null; then \ - echo "Updating Gradle wrapper from $$CURRENT_VER.x to 9.0..."; \ - gradle wrapper --gradle-version=9.0 || { echo "Error: 'gradle' command not found. Please install Gradle 9.0+ or run: rm -rf ~/.gradle/wrapper/dists/gradle-8.*"; exit 1; }; \ - fi; \ - else \ - gradle wrapper --gradle-version=9.0 || { echo "Error: 'gradle' command not found. Please install Gradle."; exit 1; }; \ + echo "Java $$JAVA_MAJOR detected - ensuring Gradle 9.1+ compatibility..."; \ + rm -rf ~/.gradle/wrapper/dists/gradle-8.* ~/.gradle/wrapper/dists/gradle-9.0*; \ + GRADLE_MAJOR=$$(grep distributionUrl gradle/wrapper/gradle-wrapper.properties 2>/dev/null | sed -E 's/.*gradle-([0-9]+)\..*/\1/'); \ + GRADLE_MINOR=$$(grep distributionUrl gradle/wrapper/gradle-wrapper.properties 2>/dev/null | sed -E 's/.*gradle-[0-9]+\.([0-9]+).*/\1/'); \ + if [ "$$GRADLE_MAJOR" -lt 9 ] || ([ "$$GRADLE_MAJOR" -eq 9 ] && [ "$$GRADLE_MINOR" -lt 1 ]); then \ + echo "Updating Gradle wrapper to 9.1.0 (current: $$GRADLE_MAJOR.$$GRADLE_MINOR)..."; \ + gradle wrapper --gradle-version=9.1.0 || { echo "Error: 'gradle' command not found. Install Gradle 9.1+ or manually clear: rm -rf ~/.gradle/wrapper/dists/gradle-{8,9.0}*"; exit 1; }; \ fi; \ - else \ - test -f ./gradlew || gradle wrapper; \ + elif [ ! -f ./gradlew ]; then \ + gradle wrapper; \ fi endif diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md index 53dd7911e..b01a4256b 100644 --- a/docs/getting-started/installation.md +++ b/docs/getting-started/installation.md @@ -239,18 +239,21 @@ gradlew.bat clean make ``` -The project includes a Gradle wrapper configured for Gradle 9.0+, which supports Java 22 through Java 25+. +The project includes a Gradle wrapper configured for Gradle 9.0+, which supports Java 22 through Java 26. ### Java Version Compatibility +Based on [Gradle's official compatibility matrix](https://docs.gradle.org/current/userguide/compatibility.html): + | Java Version | Class File Version | Gradle Required | |--------------|-------------------|-----------------| | Java 22 | 66 | 8.8+ | | Java 23 | 67 | 8.10+ | -| Java 24 | 68 | 8.12+ | -| Java 25 | 69 | 9.0+ | +| Java 24 | 68 | 8.14+ | +| Java 25 | 69 | 9.1.0+ | +| Java 26 | 70 | 9.4.0+ | -PerlOnJava uses **Gradle 9.0** (configured in `gradle/wrapper/gradle-wrapper.properties`) to support all these versions. +The Makefile automatically detects Java 25+ and upgrades the Gradle wrapper to 9.1.0 if needed. It also clears any incompatible cached Gradle distributions (8.x and 9.0.x). ### "JAVA_HOME is not set" diff --git a/src/main/java/org/perlonjava/core/Configuration.java b/src/main/java/org/perlonjava/core/Configuration.java index d453a980f..0a74709fc 100644 --- a/src/main/java/org/perlonjava/core/Configuration.java +++ b/src/main/java/org/perlonjava/core/Configuration.java @@ -33,7 +33,7 @@ public final class Configuration { * Automatically populated by Gradle/Maven during build. * DO NOT EDIT MANUALLY - this value is replaced at build time. */ - public static final String gitCommitId = "6a55c14f3"; + public static final String gitCommitId = "f262a26ad"; /** * Git commit date of the build (ISO format: YYYY-MM-DD). From 93d20cfa9d387f6cbcbf8bd4f41cc32b953ef48e Mon Sep 17 00:00:00 2001 From: Flavio Soibelmann Glock Date: Fri, 27 Mar 2026 20:09:23 +0100 Subject: [PATCH 3/4] fix: use bash-compatible syntax in check-java-gradle for Windows CI On Windows CI, Make uses Git Bash, so ifeq($(OS),Windows_NT) branches that use cmd.exe syntax fail. This change: - Removes the ifeq/else/endif and uses bash syntax throughout - Adds 2>/dev/null to numeric comparisons for portability - Adds || true to optional cleanup commands Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- Makefile | 13 +++++-------- .../java/org/perlonjava/core/Configuration.java | 2 +- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 4a3ca6e22..387fd518a 100644 --- a/Makefile +++ b/Makefile @@ -12,24 +12,21 @@ endif # Check Java/Gradle compatibility and fix if needed # For Java 25+, we need Gradle 9.1.0+ (see https://docs.gradle.org/current/userguide/compatibility.html) +# Note: On Windows CI, Make uses Git Bash, so we use bash-compatible syntax throughout check-java-gradle: -ifeq ($(OS),Windows_NT) - @if not exist gradlew gradle wrapper --gradle-version=9.1.0 -else @JAVA_MAJOR=$$(java -version 2>&1 | head -1 | sed -E 's/.*version "([0-9]+).*/\1/'); \ - if [ "$$JAVA_MAJOR" -ge 25 ]; then \ + if [ "$$JAVA_MAJOR" -ge 25 ] 2>/dev/null; then \ echo "Java $$JAVA_MAJOR detected - ensuring Gradle 9.1+ compatibility..."; \ - rm -rf ~/.gradle/wrapper/dists/gradle-8.* ~/.gradle/wrapper/dists/gradle-9.0*; \ + rm -rf ~/.gradle/wrapper/dists/gradle-8.* ~/.gradle/wrapper/dists/gradle-9.0* 2>/dev/null || true; \ GRADLE_MAJOR=$$(grep distributionUrl gradle/wrapper/gradle-wrapper.properties 2>/dev/null | sed -E 's/.*gradle-([0-9]+)\..*/\1/'); \ GRADLE_MINOR=$$(grep distributionUrl gradle/wrapper/gradle-wrapper.properties 2>/dev/null | sed -E 's/.*gradle-[0-9]+\.([0-9]+).*/\1/'); \ - if [ "$$GRADLE_MAJOR" -lt 9 ] || ([ "$$GRADLE_MAJOR" -eq 9 ] && [ "$$GRADLE_MINOR" -lt 1 ]); then \ + if [ "$$GRADLE_MAJOR" -lt 9 ] 2>/dev/null || ([ "$$GRADLE_MAJOR" -eq 9 ] 2>/dev/null && [ "$$GRADLE_MINOR" -lt 1 ] 2>/dev/null); then \ echo "Updating Gradle wrapper to 9.1.0 (current: $$GRADLE_MAJOR.$$GRADLE_MINOR)..."; \ gradle wrapper --gradle-version=9.1.0 || { echo "Error: 'gradle' command not found. Install Gradle 9.1+ or manually clear: rm -rf ~/.gradle/wrapper/dists/gradle-{8,9.0}*"; exit 1; }; \ fi; \ elif [ ! -f ./gradlew ]; then \ - gradle wrapper; \ + gradle wrapper || true; \ fi -endif wrapper: check-java-gradle diff --git a/src/main/java/org/perlonjava/core/Configuration.java b/src/main/java/org/perlonjava/core/Configuration.java index 0a74709fc..6ea50dfea 100644 --- a/src/main/java/org/perlonjava/core/Configuration.java +++ b/src/main/java/org/perlonjava/core/Configuration.java @@ -33,7 +33,7 @@ public final class Configuration { * Automatically populated by Gradle/Maven during build. * DO NOT EDIT MANUALLY - this value is replaced at build time. */ - public static final String gitCommitId = "f262a26ad"; + public static final String gitCommitId = "2620e2748"; /** * Git commit date of the build (ISO format: YYYY-MM-DD). From 3b3b10e3af1e98461838b2fb3b0e879cc64eff9e Mon Sep 17 00:00:00 2001 From: Flavio Soibelmann Glock Date: Fri, 27 Mar 2026 20:17:13 +0100 Subject: [PATCH 4/4] fix: directly update gradle-wrapper.properties instead of running gradle The old gradle command (8.x) cannot run on Java 25+ due to class file version 69. Instead of running `gradle wrapper --gradle-version=9.1.0`, we directly update the distributionUrl in gradle-wrapper.properties using sed. The wrapper script will then download the correct version. This fixes the case where users have an old system gradle installed (e.g., via sdkman) that crashes when running on Java 25+. Fixes #392 Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- Makefile | 5 +++-- src/main/java/org/perlonjava/core/Configuration.java | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 387fd518a..c022f5f5d 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,7 @@ endif # Check Java/Gradle compatibility and fix if needed # For Java 25+, we need Gradle 9.1.0+ (see https://docs.gradle.org/current/userguide/compatibility.html) # Note: On Windows CI, Make uses Git Bash, so we use bash-compatible syntax throughout +# Note: We modify gradle-wrapper.properties directly because older gradle can't run on Java 25+ check-java-gradle: @JAVA_MAJOR=$$(java -version 2>&1 | head -1 | sed -E 's/.*version "([0-9]+).*/\1/'); \ if [ "$$JAVA_MAJOR" -ge 25 ] 2>/dev/null; then \ @@ -21,8 +22,8 @@ check-java-gradle: GRADLE_MAJOR=$$(grep distributionUrl gradle/wrapper/gradle-wrapper.properties 2>/dev/null | sed -E 's/.*gradle-([0-9]+)\..*/\1/'); \ GRADLE_MINOR=$$(grep distributionUrl gradle/wrapper/gradle-wrapper.properties 2>/dev/null | sed -E 's/.*gradle-[0-9]+\.([0-9]+).*/\1/'); \ if [ "$$GRADLE_MAJOR" -lt 9 ] 2>/dev/null || ([ "$$GRADLE_MAJOR" -eq 9 ] 2>/dev/null && [ "$$GRADLE_MINOR" -lt 1 ] 2>/dev/null); then \ - echo "Updating Gradle wrapper to 9.1.0 (current: $$GRADLE_MAJOR.$$GRADLE_MINOR)..."; \ - gradle wrapper --gradle-version=9.1.0 || { echo "Error: 'gradle' command not found. Install Gradle 9.1+ or manually clear: rm -rf ~/.gradle/wrapper/dists/gradle-{8,9.0}*"; exit 1; }; \ + echo "Updating gradle-wrapper.properties to use Gradle 9.1.0 (current: $$GRADLE_MAJOR.$$GRADLE_MINOR)..."; \ + sed -i.bak 's|gradle-[0-9][0-9]*\.[0-9][0-9]*[^/]*-bin\.zip|gradle-9.1.0-bin.zip|' gradle/wrapper/gradle-wrapper.properties && rm -f gradle/wrapper/gradle-wrapper.properties.bak; \ fi; \ elif [ ! -f ./gradlew ]; then \ gradle wrapper || true; \ diff --git a/src/main/java/org/perlonjava/core/Configuration.java b/src/main/java/org/perlonjava/core/Configuration.java index 6ea50dfea..1a304bd33 100644 --- a/src/main/java/org/perlonjava/core/Configuration.java +++ b/src/main/java/org/perlonjava/core/Configuration.java @@ -33,7 +33,7 @@ public final class Configuration { * Automatically populated by Gradle/Maven during build. * DO NOT EDIT MANUALLY - this value is replaced at build time. */ - public static final String gitCommitId = "2620e2748"; + public static final String gitCommitId = "93d20cfa9"; /** * Git commit date of the build (ISO format: YYYY-MM-DD).