pgjdbc/pgjdbc GitHub issues and pull requests (mirror)
help / color / mirror / Atom feedFrom: vlsi (@vlsi) <[email protected]>
To: pgjdbc/pgjdbc <[email protected]>
Subject: [pgjdbc/pgjdbc] PR #4150: build: 42.4 compile with a Java 17 toolchain, run tests on multiple JDKs
Date: Thu, 04 Jun 2026 07:35:18 +0000
Message-ID: <[email protected]> (raw)
## Why
The 42.4.x build ties the compile JDK to the JVM that runs Gradle and sets the target through `sourceCompatibility`/`targetCompatibility`. That makes it hard to build on a fixed JDK while running the test suite against several Java versions, the model already used on `master`.
The build runs on JDK 17 and still targets Java 8 bytecode (`javac --release 8`).
## What
- Add a Gradle toolchain for the main modules. `jdkBuildVersion` (default 17) selects the compile JDK; the driver still produces Java 8 bytecode via `javac --release 8`.
- Replace `sourceCompatibility`/`targetCompatibility` with `javac --release 8`, guarded so it is only passed on `javac` 9+ (no effect on JDK 8).
- Run the test task on a separate JDK via `-PjdkTestVersion` (0 reuses the build JVM), using a toolchain launcher.
- Stop forwarding the build JVM's `java.*` system properties to the test JVM. Forwarding `java.home`/`java.version` broke a test JVM running on a different Java version; only `pgjdbc.*` is forwarded now, matching `master`.
- CI: build on JDK 17 and run the `[8, 11, 17]` test matrix through the toolchain launcher (`jdkTestVersion` + `org.gradle.java.installations.fromEnv` + `auto-download=false`). The matrix `java_version` flows into the build as `jdkTestVersion`.
- CI jobs that compile (`code-style`, `linux-checkerframework`, `source-distribution-check`, GSS deploy) now run on JDK 17.
## How to verify
```
# Compiles on JDK 17, produces Java 8 bytecode (Driver.class major version = 52)
JAVA_HOME=<jdk17> ./gradlew :postgresql:compileJava
# Runs the tests on JDK 8 while the build stays on JDK 17
JAVA_HOME=<jdk17> ./gradlew :postgresql:test -PjdkTestVersion=8
```
Verified locally:
- `:postgresql:compileJava` compiles via the JDK 17 toolchain (`Compiling with toolchain '.../17.0.10-librca'`).
- `Driver.class` bytecode major version is `52` (Java 8).
- `org.postgresql.util.PGtokenizerTest` runs on JDK 8 (test executor java path `.../8.0.402-librca/bin/java`) and passes (5 tests, 0 failures).
- The build script configures cleanly across all projects on JDK 17.
CI was verified by reading only (the workflow YAML was validated with `python3 yaml.safe_load`); the GitHub Actions runs themselves were not executed locally.
## Notes
- `jdkBuildVersion` defaults to 17, so the build now expects a JDK 17 toolchain. Pass `-PjdkBuildVersion=0` to compile with the current JVM instead.
- There are no `postgresql-jre6`/`jre7` modules on this branch, so no per-module toolchain guard is needed.
- The CI `fromEnv` entries use the `_X64` arch suffix. The ARM64 path (`AdoptOpenJDK/install-jdk`) installs JDK 17 as the default JVM, but its `JAVA_HOME_*` arch suffix is `AARCH64`, which the x64 `fromEnv` list does not cover. This is a best-effort gap for ARM64 runners; the x64 path is the focus and is correct.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
diff --git a/.github/workflows/buildcache.yml b/.github/workflows/buildcache.yml
index b8074033d2..a42d7e560f 100644
--- a/.github/workflows/buildcache.yml
+++ b/.github/workflows/buildcache.yml
@@ -43,7 +43,9 @@ jobs:
strategy:
matrix:
os: [ubuntu, macos, windows]
- jdk: [8, 11]
+ # build -x test does not run tests, so only the build JDK matters here.
+ # The driver compiles via a JDK 17 toolchain (still targeting Java 8 bytecode).
+ jdk: [17]
name: '${{ matrix.os }}, ${{ matrix.jdk }} seed build cache'
runs-on: ${{ matrix.os }}-latest
@@ -52,8 +54,9 @@ jobs:
with:
fetch-depth: 50
- name: 'Set up JDK ${{ matrix.jdk }}'
- uses: actions/setup-java@v1
+ uses: actions/setup-java@v3
with:
+ distribution: zulu
java-version: ${{ matrix.jdk }}
- uses: burrunan/gradle-cache-action@v1
name: Build pgjdbc
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index c0f9b108f1..6703a13abf 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -44,11 +44,11 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 50
- - name: 'Set up JDK 8'
+ - name: 'Set up JDK 17'
uses: actions/setup-java@v3
with:
distribution: zulu
- java-version: 8
+ java-version: 17
- uses: burrunan/gradle-cache-action@v1
name: Verify code style
env:
@@ -65,6 +65,7 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 50
+ # CheckerFramework 3.5.0 cannot access javac internals on JDK 16+, so run it on JDK 11.
- name: 'Set up JDK 11'
uses: actions/setup-java@v3
with:
@@ -78,10 +79,10 @@ jobs:
with:
read-only: ${{ matrix.os == 'self-hosted' }}
job-id: checker-jdk11
- arguments: --scan --no-parallel --no-daemon -PenableCheckerframework classes
+ arguments: --scan --no-parallel --no-daemon -PenableCheckerframework classes -PjdkBuildVersion=11
source-distribution-check:
- name: 'Source distribution (JDK 11)'
+ name: 'Source distribution (JDK 17)'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@@ -90,11 +91,11 @@ jobs:
- name: Start PostgreSQL
working-directory: docker/postgres-server
run: docker compose up -d && docker compose logs
- - name: 'Set up JDK 11'
+ - name: 'Set up JDK 17'
uses: actions/setup-java@v3
with:
distribution: zulu
- java-version: 11
+ java-version: 17
- uses: burrunan/gradle-cache-action@v1
name: Prepare source distribution
env:
@@ -160,11 +161,16 @@ jobs:
- name: 'Get test node ARCH'
run: echo "::set-output name=arch_name::$(uname -i)"
id: get_arch_name
- - name: Set up Java ${{ matrix.java_version }}, ${{ matrix.java_distribution }}
+ - name: Set up Java ${{ matrix.java_version }} (test) and 17 (build), ${{ matrix.java_distribution }}
if: ${{ steps.get_arch_name.outputs.arch_name != 'aarch64' }}
uses: actions/setup-java@v3
with:
- java-version: ${{ matrix.java_version }}
+ # Install the test JDK and the build JDK 17. The last entry becomes the default
+ # JAVA_HOME, so Gradle runs on JDK 17 while tests run on matrix.java_version via a
+ # toolchain launcher (jdkTestVersion). Both env vars are picked up via fromEnv below.
+ java-version: |
+ ${{ matrix.java_version }}
+ 17
distribution: ${{ matrix.java_distribution }}
architecture: x64
- name: 'Setup JDK ${{ matrix.java_version }} on ARM64'
@@ -174,6 +180,14 @@ jobs:
impl: hotspot # or openj9
version: ${{ matrix.java_version }}
architecture: aarch64
+ - name: 'Setup build JDK 17 on ARM64'
+ # Install JDK 17 last so it becomes the default JAVA_HOME used to run Gradle.
+ if: ${{ steps.get_arch_name.outputs.arch_name == 'aarch64' }}
+ uses: AdoptOpenJDK/install-jdk@v1
+ with:
+ impl: hotspot # or openj9
+ version: '17'
+ architecture: aarch64
- name: Prepare local properties
run: |
# See https://github.com/actions/runner/issues/409
@@ -196,6 +210,11 @@ jobs:
arguments: --scan --no-parallel --no-daemon jandex test
properties: |
includeTestTags=${{ matrix.includeTestTags }}
+ jdkBuildVersion=17
+ jdkTestVersion=${{ matrix.java_version }}
+ org.gradle.java.installations.fromEnv=JAVA_HOME_${{ matrix.java_version }}_X64,JAVA_HOME_17_X64
+ # We provision JDKs via GitHub Actions, so Gradle should fail rather than download a missing JDK
+ org.gradle.java.installations.auto-download=false
- name: 'Install krb5 for GSS tests'
if: ${{ matrix.gss == 'yes' }}
@@ -214,6 +233,11 @@ jobs:
read-only: ${{ matrix.os == 'self-hosted' }}
job-id: jdk${{ matrix.java_version }}
arguments: publishToMavenLocal -Ppgjdbc.version=1.0.0-dev-master -PskipJavadoc
+ properties: |
+ jdkBuildVersion=17
+ org.gradle.java.installations.fromEnv=JAVA_HOME_${{ matrix.java_version }}_X64,JAVA_HOME_17_X64
+ # We provision JDKs via GitHub Actions, so Gradle should fail rather than download a missing JDK
+ org.gradle.java.installations.auto-download=false
- name: Test GSS
if: ${{ matrix.gss == 'yes' }}
run: |
diff --git a/build.gradle.kts b/build.gradle.kts
index 45d4a537a9..3ab0a25aaf 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -13,6 +13,8 @@ import com.github.vlsi.gradle.publishing.dsl.simplifyXml
import com.github.vlsi.gradle.publishing.dsl.versionFromResolution
import de.thetaphi.forbiddenapis.gradle.CheckForbiddenApis
import de.thetaphi.forbiddenapis.gradle.CheckForbiddenApisExtension
+import org.gradle.jvm.toolchain.JavaLanguageVersion
+import org.gradle.jvm.toolchain.JavaToolchainService
import org.postgresql.buildtools.JavaCommentPreprocessorTask
buildscript {
@@ -65,6 +67,10 @@ val skipJavadoc by props()
val skipForbiddenApis by props()
val enableMavenLocal by props()
val enableGradleMetadata by props()
+// Java version used to compile the driver via a toolchain. 0 falls back to the JVM that runs Gradle.
+val jdkBuildVersion = props.int("jdkBuildVersion", 17)
+// Java version used to run the test task via a toolchain. 0 reuses the build JVM.
+val jdkTestVersion = props.int("jdkTestVersion", 0)
// For instance -PincludeTestTags=!org.postgresql.test.SlowTests
// or -PincludeTestTags=!org.postgresql.test.Replication
val includeTestTags by props("")
@@ -379,12 +385,17 @@ allprojects {
plugins.withType<JavaPlugin> {
configure<JavaPluginExtension> {
- sourceCompatibility = JavaVersion.VERSION_1_8
- targetCompatibility = JavaVersion.VERSION_1_8
withSourcesJar()
if (!skipJavadoc) {
withJavadocJar()
}
+ // Compile the driver via a toolchain so the build JVM can differ from the
+ // JVM used to compile. The bytecode target stays Java 8 via javac --release 8.
+ if (jdkBuildVersion != 0) {
+ toolchain {
+ languageVersion.set(JavaLanguageVersion.of(jdkBuildVersion))
+ }
+ }
}
val sourceSets: SourceSetContainer by project
@@ -537,8 +548,20 @@ allprojects {
configureEach<JavaCompile> {
options.encoding = "UTF-8"
+ // Target Java 8 bytecode without referencing Java 9+ API (--release needs javac 9+).
+ options.release.set(
+ provider { 8.takeIf { javaCompiler.get().metadata.languageVersion.asInt() > 9 } }
+ )
}
configureEach<Test> {
+ // Run tests on a specific Java version, independent of the build JVM.
+ if (jdkTestVersion != 0) {
+ javaLauncher.set(
+ project.the<JavaToolchainService>().launcherFor {
+ languageVersion.set(JavaLanguageVersion.of(jdkTestVersion))
+ }
+ )
+ }
useJUnitPlatform {
if (includeTestTags.isNotBlank()) {
includeTags.add(includeTestTags)
@@ -574,7 +597,10 @@ allprojects {
passProperty("user.country", "tr")
val props = System.getProperties()
for (e in props.propertyNames() as `java.util`.Enumeration<String>) {
- if (e.startsWith("pgjdbc.") || e.startsWith("java")) {
+ // Forward only pgjdbc.* here. Forwarding the build JVM's java.* properties
+ // (java.home, java.version, ...) would break a test JVM on a different
+ // Java version selected via jdkTestVersion.
+ if (e.startsWith("pgjdbc.")) {
passProperty(e)
}
}
diff --git a/gradle.properties b/gradle.properties
index a3261793e9..392b428748 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -15,6 +15,12 @@ kotlin.code.style=official
# Release version can be generated by using -Prelease or -Prc=<int> arguments
pgjdbc.version=42.4.6
+# Java version used to compile the driver via a Gradle toolchain (still targets Java 8 bytecode).
+# Set to 0 to compile with the JVM that runs Gradle.
+jdkBuildVersion=17
+# Java version used to run tests via a Gradle toolchain. 0 reuses the build JVM. e.g. -PjdkTestVersion=8
+jdkTestVersion=0
+
# The options below configures the use of local clone (e.g. testing development versions)
# You can pass un-comment it, or pass option -PlocalReleasePlugins, or -PlocalReleasePlugins=<path>
# localReleasePlugins=../vlsi-release-plugins
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: github://pgjdbc/pgjdbc
Cc: [email protected], [email protected]
Subject: Re: [pgjdbc/pgjdbc] PR #4150: build: 42.4 compile with a Java 17 toolchain, run tests on multiple JDKs
In-Reply-To: <<[email protected]>>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox