This is an automated email from the ASF dual-hosted git repository.

vlsi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git

commit 8dcfd128025ebb47ae3a2a7dad6ee6af29e30bf0
Author: Vladimir Sitnikov <[email protected]>
AuthorDate: Mon Sep 21 19:43:38 2026 +0300

    [CALCITE-4553] Use Gradle toolchain to compile Calcite with JDK 25 and 
--release 8
    
    Previously javac came from the JDK that ran Gradle, so the compiler version
    varied with each CI job and each developer's JAVA_HOME, and only
    sourceCompatibility/targetCompatibility 1.8 kept the bytecode at Java 8
    without checking the JDK 8 API. Older javac versions also have known bugs
    with type annotations, which Calcite uses for nullability.
    
    JavaCompile tasks now take their compiler from a toolchain,
    jdkBuildVersion (default 25), and pass --release 8, which also rejects
    calls to APIs newer than Java 8. Tests, javadoc, and JavaExec tasks still
    run on the JDK that runs Gradle.
    
    The foojay resolver downloads the toolchain when no matching JDK is
    installed. It stays at 0.10.0 because 1.0.0 requires Gradle to run on
    Java 17, and CI still runs Gradle on Java 8 and 11. When Gradle runs on
    Java 8, the download fails anyway: api.foojay.io answers the Java 8
    User-Agent with "error code: 1010", so the build JDK must be installed.
    
    CI installs JDK 25 next to the JDK each job tests with, and sets
    org.gradle.java.installations.auto-download=false, so a build fails
    instead of silently compiling with a JDK that foojay downloaded.
    The ErrorProne and Checker Framework jobs pass -PjdkBuildVersion=11:
    ErrorProne 2.5.1 fails on JDK 25 with
    "IllegalAccessError: class 
com.google.errorprone.JavacErrorDescriptionListener
    ... cannot access class com.sun.tools.javac.tree.JCTree$JCCompilationUnit".
    
    Co-Authored-By: Claude Opus 5 <[email protected]>
---
 .github/workflows/main.yml | 107 +++++++++++++++++++++++++++++++++------------
 build.gradle.kts           |  10 ++++-
 gradle.properties          |   1 +
 settings.gradle.kts        |   2 +
 4 files changed, 91 insertions(+), 29 deletions(-)

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 37488ffc7d..bb3d609db5 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -58,10 +58,12 @@ jobs:
     - uses: actions/checkout@v7
       with:
         fetch-depth: 50
-    - name: 'Set up JDK 8'
+    - name: 'Set up JDK 25 for compilation and JDK 8 for tests'
       uses: actions/setup-java@v6
       with:
-        java-version: 8
+        java-version: |
+          25
+          8
         distribution: 'zulu'
     - uses: burrunan/gradle-cache-action@v1
       name: Test
@@ -69,6 +71,8 @@ jobs:
         job-id: jdk${{ matrix.jdk }}
         remote-build-cache-proxy-enabled: false
         arguments: --scan --no-parallel --no-daemon build javadoc
+        properties: |
+          org.gradle.java.installations.auto-download=false
     - name: 'sqlline and sqllsh'
       env:
         JAVA_OPTS: "-Dcalcite.model.classes.allowed=org.apache."
@@ -89,10 +93,12 @@ jobs:
       - uses: actions/checkout@v7
         with:
           fetch-depth: 50
-      - name: 'Set up JDK 17'
+      - name: 'Set up JDK 25 for compilation and JDK 17 for tests'
         uses: actions/setup-java@v6
         with:
-          java-version: 17
+          java-version: |
+            25
+            17
           distribution: 'zulu'
       - uses: burrunan/gradle-cache-action@v1
         name: Test
@@ -100,6 +106,8 @@ jobs:
           job-id: jdk${{ matrix.jdk }}
           remote-build-cache-proxy-enabled: false
           arguments: --scan --no-parallel --no-daemon build
+          properties: |
+            org.gradle.java.installations.auto-download=false
       - name: 'sqlline and sqllsh'
         env:
           JAVA_OPTS: "-Dcalcite.model.classes.allowed=org.apache."
@@ -120,10 +128,12 @@ jobs:
       - uses: actions/checkout@v7
         with:
           fetch-depth: 50
-      - name: 'Set up JDK 21'
+      - name: 'Set up JDK 25 for compilation and JDK 21 for tests'
         uses: actions/setup-java@v6
         with:
-          java-version: 21
+          java-version: |
+            25
+            21
           distribution: 'zulu'
       - uses: burrunan/gradle-cache-action@v1
         name: Test
@@ -131,6 +141,8 @@ jobs:
           job-id: jdk${{ matrix.jdk }}
           remote-build-cache-proxy-enabled: false
           arguments: --scan --no-parallel --no-daemon build
+          properties: |
+            org.gradle.java.installations.auto-download=false
       - name: 'sqlline and sqllsh'
         env:
           JAVA_OPTS: "-Dcalcite.model.classes.allowed=org.apache."
@@ -153,10 +165,12 @@ jobs:
       - uses: actions/checkout@v7
         with:
           fetch-depth: 50
-      - name: 'Set up JDK 8'
+      - name: 'Set up JDK 25 for compilation and JDK 8 for tests'
         uses: actions/setup-java@v6
         with:
-          java-version: 8
+          java-version: |
+            25
+            8
           distribution: 'zulu'
       - uses: burrunan/gradle-cache-action@v1
         name: Test
@@ -164,6 +178,8 @@ jobs:
           job-id: jdk${{ matrix.jdk }}
           remote-build-cache-proxy-enabled: false
           arguments: --scan --no-parallel --no-daemon -Pguava.version=${{ 
env.GUAVA_MIN }} build
+          properties: |
+            org.gradle.java.installations.auto-download=false
 
   linux-jdk8-latest-guava-tz:
     name: 'Linux (JDK 8, latest Guava, America/New_York Timezone)'
@@ -174,10 +190,12 @@ jobs:
       - uses: actions/checkout@v7
         with:
           fetch-depth: 50
-      - name: 'Set up JDK 8'
+      - name: 'Set up JDK 25 for compilation and JDK 8 for tests'
         uses: actions/setup-java@v6
         with:
-          java-version: 8
+          java-version: |
+            25
+            8
           distribution: 'zulu'
       - uses: burrunan/gradle-cache-action@v1
         name: Test
@@ -185,6 +203,8 @@ jobs:
           job-id: jdk${{ matrix.jdk }}
           remote-build-cache-proxy-enabled: false
           arguments: --scan --no-parallel --no-daemon -Pguava.version=${{ 
env.GUAVA_MAX }} tasks build
+          properties: |
+            org.gradle.java.installations.auto-download=false
 
   linux-jdk11-tz:
     name: 'Linux (JDK 11, Pacific/Chatham Timezone)'
@@ -195,10 +215,12 @@ jobs:
       - uses: actions/checkout@v7
         with:
           fetch-depth: 50
-      - name: 'Set up JDK 11'
+      - name: 'Set up JDK 25 for compilation and JDK 11 for tests'
         uses: actions/setup-java@v6
         with:
-          java-version: 11
+          java-version: |
+            25
+            11
           distribution: 'zulu'
       - uses: burrunan/gradle-cache-action@v1
         name: Test
@@ -206,6 +228,8 @@ jobs:
           job-id: jdk${{ matrix.jdk }}
           remote-build-cache-proxy-enabled: false
           arguments: --scan --no-parallel --no-daemon build
+          properties: |
+            org.gradle.java.installations.auto-download=false
 
   linux-jdk17:  # LTS JDK version, don't remove until EOL
     name: 'Linux (JDK 17)'
@@ -214,10 +238,12 @@ jobs:
       - uses: actions/checkout@v7
         with:
           fetch-depth: 50
-      - name: 'Set up JDK 17'
+      - name: 'Set up JDK 25 for compilation and JDK 17 for tests'
         uses: actions/setup-java@v6
         with:
-          java-version: 17
+          java-version: |
+            25
+            17
           distribution: 'zulu'
       - uses: burrunan/gradle-cache-action@v1
         name: Test
@@ -225,6 +251,8 @@ jobs:
           job-id: jdk${{ matrix.jdk }}
           remote-build-cache-proxy-enabled: false
           arguments: --scan --no-parallel --no-daemon -Pguava.version=${{ 
env.GUAVA }} build
+          properties: |
+            org.gradle.java.installations.auto-download=false
 
   linux-jdk121:  # LTS JDK version, don't remove until EOL
     name: 'Linux (JDK 21)'
@@ -233,10 +261,12 @@ jobs:
       - uses: actions/checkout@v7
         with:
           fetch-depth: 50
-      - name: 'Set up JDK 21'
+      - name: 'Set up JDK 25 for compilation and JDK 21 for tests'
         uses: actions/setup-java@v6
         with:
-          java-version: 21
+          java-version: |
+            25
+            21
           distribution: 'zulu'
       - uses: burrunan/gradle-cache-action@v1
         name: Test
@@ -244,6 +274,8 @@ jobs:
           job-id: jdk${{ matrix.jdk }}
           remote-build-cache-proxy-enabled: false
           arguments: --scan --no-parallel --no-daemon -Pguava.version=${{ 
env.GUAVA }} build
+          properties: |
+            org.gradle.java.installations.auto-download=false
 
   linux-jdk24: # latest JDK version supported by ForbiddenAPIs plugin, keep 
this updated (see https://jdk.java.net/)
     name: 'Linux (JDK 24)'
@@ -252,10 +284,12 @@ jobs:
       - uses: actions/checkout@v7
         with:
           fetch-depth: 50
-      - name: 'Set up JDK 24'
+      - name: 'Set up JDK 25 for compilation and JDK 24 for tests'
         uses: actions/setup-java@v6
         with:
-          java-version: 24
+          java-version: |
+            25
+            24
           distribution: 'zulu'
       - uses: burrunan/gradle-cache-action@v1
         name: Test
@@ -263,15 +297,19 @@ jobs:
           job-id: jdk${{ matrix.jdk }}
           remote-build-cache-proxy-enabled: false
           arguments: --scan --no-parallel --no-daemon -Pguava.version=${{ 
env.GUAVA }} tasks build
+          properties: |
+            org.gradle.java.installations.auto-download=false
 
   linux-avatica:
     name: 'Linux (JDK 11, Avatica main)'
     runs-on: ubuntu-latest
     steps:
-    - name: 'Set up JDK 11'
+    - name: 'Set up JDK 25 for compilation and JDK 11 for tests'
       uses: actions/setup-java@v6
       with:
-        java-version: 11
+        java-version: |
+          25
+          11
         distribution: 'zulu'
     - name: 'Clone Avatica to Maven Local repository'
       run: |
@@ -297,6 +335,7 @@ jobs:
         execution-only-caches: true
         arguments: --scan --no-parallel --no-daemon build javadoc
         properties: |
+          org.gradle.java.installations.auto-download=false
           calcite.avatica.version=1.0.0-dev-main-SNAPSHOT
           enableMavenLocal=
 
@@ -307,10 +346,12 @@ jobs:
       - uses: actions/checkout@v7
         with:
           fetch-depth: 50
-      - name: 'Set up JDK 21'
+      - name: 'Set up JDK 25 for compilation and JDK 21 for tests'
         uses: actions/setup-java@v6
         with:
-          java-version: 21
+          java-version: |
+            25
+            21
           distribution: 'zulu'
       - uses: burrunan/gradle-cache-action@v1
         name: Test
@@ -318,6 +359,8 @@ jobs:
           job-id: jdk21
           remote-build-cache-proxy-enabled: false
           arguments: --scan --no-parallel --no-daemon build javadoc
+          properties: |
+            org.gradle.java.installations.auto-download=false
       - name: 'sqlline and sqllsh'
         env:
           JAVA_OPTS: "-Dcalcite.model.classes.allowed=org.apache."
@@ -348,7 +391,9 @@ jobs:
           job-id: errprone
           remote-build-cache-proxy-enabled: false
           # ErrorProne checks for Beta APIs, so use the latest supported Guava 
version
-          arguments: --scan --no-parallel --no-daemon -Pguava.version=${{ 
env.GUAVA_MAX }} -PenableErrorprone classes
+          arguments: --scan --no-parallel --no-daemon -PjdkBuildVersion=11 
-Pguava.version=${{ env.GUAVA_MAX }} -PenableErrorprone classes
+          properties: |
+            org.gradle.java.installations.auto-download=false
 
   linux-checkerframework:
     name: 'CheckerFramework (JDK 11)'
@@ -367,7 +412,9 @@ jobs:
         with:
           job-id: checkerframework-jdk11
           remote-build-cache-proxy-enabled: false
-          arguments: --scan --no-parallel --no-daemon -PenableCheckerframework 
:linq4j:classes :core:classes :server:classes
+          arguments: --scan --no-parallel --no-daemon -PjdkBuildVersion=11 
-PenableCheckerframework :linq4j:classes :core:classes :server:classes
+          properties: |
+            org.gradle.java.installations.auto-download=false
 
   linux-checkerframework-oldest-guava:
     name: 'CheckerFramework (JDK 11, oldest Guava)'
@@ -386,16 +433,20 @@ jobs:
         with:
           job-id: checkerframework-jdk11
           remote-build-cache-proxy-enabled: false
-          arguments: --scan --no-parallel --no-daemon -Pguava.version=${{ 
env.GUAVA_MIN }} -PenableCheckerframework :linq4j:classes :core:classes 
:server:classes
+          arguments: --scan --no-parallel --no-daemon -PjdkBuildVersion=11 
-Pguava.version=${{ env.GUAVA_MIN }} -PenableCheckerframework :linq4j:classes 
:core:classes :server:classes
+          properties: |
+            org.gradle.java.installations.auto-download=false
 
   linux-druid:
     name: 'Druid Tests'
     runs-on: ubuntu-latest
     steps:
-    - name: 'Set up JDK 17'
+    - name: 'Set up JDK 25 for compilation and JDK 17 for tests'
       uses: actions/setup-java@v6
       with:
-        java-version: 17
+        java-version: |
+          25
+          17
         distribution: 'zulu'
     - name: 'Checkout Druid dataset'
       uses: actions/checkout@v7
@@ -430,3 +481,5 @@ jobs:
         job-id: Druid8
         remote-build-cache-proxy-enabled: false
         arguments: --scan --no-parallel --no-daemon :druid:test 
-Dcalcite.test.druid=true
+        properties: |
+          org.gradle.java.installations.auto-download=false
diff --git a/build.gradle.kts b/build.gradle.kts
index 4a45616720..6d5c4747a9 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -91,6 +91,8 @@ fun reportsForHumans() = !(System.getenv()["CI"]?.toBoolean() 
?: false)
 val enableMavenLocal by props()
 val enableGradleMetadata by props()
 val werror by props(true) // treat javac warnings as errors
+// JDK that compiles the code; the bytecode still targets Java 8 via --release 
8
+val jdkBuildVersion = props.int("jdkBuildVersion", 25)
 // Inherited from stage-vote-release-plugin: skipSign, useGpgCmd
 // Inherited from gradle-extensions-plugin: slowSuiteLogThreshold=0L, 
slowTestLogThreshold=2000L
 
@@ -872,8 +874,12 @@ fun 
com.github.autostyle.gradle.BaseFormatExtension.license() {
             }
 
             configureEach<JavaCompile> {
-                inputs.property("java.version", 
System.getProperty("java.version"))
-                inputs.property("java.vm.version", 
System.getProperty("java.vm.version"))
+                javaCompiler.set(
+                    project.the<JavaToolchainService>().compilerFor {
+                        
languageVersion.set(JavaLanguageVersion.of(jdkBuildVersion))
+                    }
+                )
+                options.release.set(8)
                 options.encoding = "UTF-8"
                 options.compilerArgs.add("-Xlint:deprecation")
                 // JDK 1.8 is deprecated 
https://bugs.openjdk.org/browse/JDK-8173605
diff --git a/gradle.properties b/gradle.properties
index 2027c6f82a..2f9bed80d2 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -59,6 +59,7 @@ org.owasp.dependencycheck.version=12.2.2
 org.sonarqube.version=3.5.0.2730
 com.gradle.develocity.version=4.5.1
 com.gradle.common-custom-user-data-gradle-plugin.version=2.8.0
+org.gradle.toolchains.foojay-resolver-convention.version=0.10.0
 
 
 # For now, we use Kotlin for tests only, so we don't want to include 
kotlin-stdlib dependency to the runtimeClasspath
diff --git a/settings.gradle.kts b/settings.gradle.kts
index fbc3502a7c..c0138f48ce 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -43,6 +43,7 @@ fun PluginDependenciesSpec.idv(id: String, key: String = id) 
= id(id) version ke
             idv("org.owasp.dependencycheck")
         }
         idv("org.sonarqube")
+        idv("org.gradle.toolchains.foojay-resolver-convention")
         kotlin("jvm") version "kotlin".v()
     }
     if (extra.has("enableMavenLocal") && 
extra["enableMavenLocal"].toString().ifBlank { "true" }.toBoolean()) {
@@ -54,6 +55,7 @@ fun PluginDependenciesSpec.idv(id: String, key: String = id) 
= id(id) version ke
 }
 
 plugins {
+    id("org.gradle.toolchains.foojay-resolver-convention")
     id("com.gradle.develocity")
     id("com.gradle.common-custom-user-data-gradle-plugin")
 }

Reply via email to