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 #4151: build: 42.3 compile with a Java 17 toolchain, run tests on multiple JDKs
Date: Thu, 04 Jun 2026 07:35:20 +0000
Message-ID: <[email protected]> (raw)
## Why
The 42.3.x build tied the compile JDK to the JVM running Gradle and set the target via `sourceCompatibility`/`targetCompatibility`. That makes it hard to build on a fixed JDK while testing against several Java versions — the model already used on `master`.
Rebased on top of the Gradle 7.6.6 migration on `release/42.3.x`. The build now uses a **Java 17 toolchain** (matching 42.4.x/42.5.x/42.6.x) while still emitting **Java 8 bytecode**.
## What
- Add a Gradle toolchain for the main modules. `jdkBuildVersion` (default 17) selects the compile JDK; the driver still targets Java 8.
- Replace `sourceCompatibility`/`targetCompatibility` with `javac --release 8`, guarded to javac 9+.
- 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; only `pgjdbc.*` is forwarded now, matching `master`.
### Making 42.3.x build on JDK 17
- **bnd**: bump `biz.aQute.bnd.builder` 4.3.1 → 6.3.1. 4.3.1 fails on JDK 17 (this broke `osgiJar`); 6.3.1 is already used on 42.5.x.
- **javadoc**: add `-Xdoclint:all,-missing`, drop the redirecting `javase/9` element-list links on JDK 17+, and document with `--release 8` so the `AccessController` deprecation-for-removal warning does not fail `-Xwerror`.
- **CheckerFramework** job runs on JDK 11; its pinned CheckerFramework 3.5.0 cannot access javac internals on JDK 16+.
- **test-gss**: bump its Gradle wrapper 6.1 → 7.6.6 (6.1 fails on JDK 17), plus the changes that requires — `testCompile` → `testImplementation` and `groovy-all` 2.5.12 → 3.0.11.
- **source distribution**: add a JDK 16+ Maven profile that opens `java.base` so System Stubs can mock environment variables under `mvn verify`.
## How to verify
```
./gradlew :postgresql:compileJava # JDK 17 toolchain, Driver.class major version 52 (Java 8)
./gradlew :postgresql:javadocJar :postgresql:osgiJar # clean on JDK 17
./gradlew :postgresql:test -PjdkTestVersion=8 # tests run on JDK 8
```
Verified locally on Gradle 7.6.6 / JDK 17: compile (bytecode 52), `javadoc`, `javadocJar`, `osgiJar`, `sourcesJar` all build cleanly; `-PjdkTestVersion=8` forks the test JVM on JDK 8 and passes; the source distribution's `mvn` tests (`OSUtilTest`, `PGPropertyPasswordParserTest`, `PGPropertyServiceParserTest`) pass on JDK 17.
## Notes
- `jdkBuildVersion` defaults to 17; pass `-PjdkBuildVersion=0` to compile with the current JVM.
- CI changes are verified by reading (they only run on GitHub Actions). The active matrix is x64 `ubuntu-latest`; the ARM64 path and `fromEnv` arch suffix (`_X64`) are a best-effort follow-up.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
diff --git a/.github/workflows/buildcache.yml b/.github/workflows/buildcache.yml
index ef344a8df9..5923898686 100644
--- a/.github/workflows/buildcache.yml
+++ b/.github/workflows/buildcache.yml
@@ -40,7 +40,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
@@ -49,8 +51,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 3e037f096a..381b10d537 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -41,11 +41,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:
@@ -62,6 +62,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:
@@ -75,10 +76,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
@@ -87,18 +88,18 @@ 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:
S3_BUILD_CACHE_ACCESS_KEY_ID: ${{ secrets.S3_BUILD_CACHE_ACCESS_KEY_ID }}
S3_BUILD_CACHE_SECRET_KEY: ${{ secrets.S3_BUILD_CACHE_SECRET_KEY }}
with:
- job-id: source-release-jdk11
+ job-id: source-release-jdk17
arguments: --scan --no-parallel --no-daemon sourceDistribution -Ppgjdbc.version=1.0 -Prelease
- name: Verify source distribution
working-directory: pgjdbc/build/distributions
@@ -117,7 +118,7 @@ jobs:
run: |
node -p "
'::set-output name=matrix::' + JSON.stringify({
- jdk: [
+ testJdkVersion: [
8,
11,
],
@@ -127,7 +128,7 @@ jobs:
})"
build-test:
- name: 'Test - JDK ${{ matrix.jdk }} on ${{ matrix.os }}'
+ name: 'Test - build JDK 17, test JDK ${{ matrix.testJdkVersion }} on ${{ matrix.os }}'
runs-on: ${{ matrix.os }}
needs: matrix_prep
strategy:
@@ -150,19 +151,23 @@ jobs:
- name: 'Get test node ARCH'
run: echo "::set-output name=arch_name::$(uname -i)"
id: get_arch_name
- - name: 'Set up JDK ${{ matrix.jdk }}'
+ - name: 'Set up test JDK ${{ matrix.testJdkVersion }} and build JDK 17'
if: ${{ steps.get_arch_name.outputs.arch_name != 'aarch64' }}
uses: actions/setup-java@v3
with:
distribution: zulu
- java-version: ${{ matrix.jdk }}
+ # The last version becomes the default JAVA_HOME, so Gradle (and the build) runs on JDK 17.
+ # The test task is launched on JDK ${{ matrix.testJdkVersion }} via the Gradle toolchain.
+ java-version: |
+ ${{ matrix.testJdkVersion }}
+ 17
architecture: x64
- - name: 'Setup JDK ${{ matrix.jdk }} on ARM64'
+ - name: 'Setup test JDK ${{ matrix.testJdkVersion }} and build JDK 17 on ARM64'
if: ${{ steps.get_arch_name.outputs.arch_name == 'aarch64' }}
uses: AdoptOpenJDK/install-jdk@v1
with:
impl: hotspot # or openj9
- version: ${{ matrix.jdk }}
+ version: ${{ matrix.testJdkVersion }}
architecture: aarch64
- name: Prepare ssltest.local.properties
run: echo enable_ssl_tests=true > ssltest.local.properties
@@ -173,10 +178,14 @@ jobs:
S3_BUILD_CACHE_SECRET_KEY: ${{ secrets.S3_BUILD_CACHE_SECRET_KEY }}
with:
read-only: ${{ matrix.os == 'self-hosted' }}
- job-id: jdk${{ matrix.jdk }}
+ job-id: jdk${{ matrix.testJdkVersion }}
arguments: --scan --no-parallel --no-daemon jandex test
properties: |
includeTestTags=!org.postgresql.test.SlowTests & !org.postgresql.test.Replication
+ jdkBuildVersion=17
+ jdkTestVersion=${{ matrix.testJdkVersion }}
+ org.gradle.java.installations.fromEnv=JAVA_HOME_${{ matrix.testJdkVersion }}_X64,JAVA_HOME_17_X64
+ org.gradle.java.installations.auto-download=false
- name: Cleanup Docker
if: ${{ always() }}
working-directory: docker/postgres-server
@@ -185,12 +194,9 @@ jobs:
docker compose down -v --rmi local
gss-encryption:
- name: 'GSS Test - JDK ${{ matrix.jdk }} on ${{ matrix.os }}'
- runs-on: ${{ matrix.os }}
- needs: matrix_prep
- strategy:
- fail-fast: false
- matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}}
+ # The driver is built on JDK 17, so this job no longer varies by the test JDK matrix.
+ name: 'GSS Test - JDK 17 on ubuntu-latest'
+ runs-on: ubuntu-latest
env:
ACTIONS_STEP_DEBUG: true
ACTIONS_RUNNER_DEBUG: true
@@ -199,18 +205,18 @@ jobs:
- name: 'Get test node ARCH'
run: echo "::set-output name=arch_name::$(uname -i)"
id: get_arch_name
- - name: 'Set up JDK 8'
+ - name: 'Set up JDK 17'
if: ${{ steps.get_arch_name.outputs.arch_name != 'aarch64' }}
uses: actions/setup-java@v3
with:
distribution: zulu
- java-version: 8
- - name: 'Setup JDK 8 on ARM64'
+ java-version: 17
+ - name: 'Setup JDK 17 on ARM64'
if: ${{ steps.get_arch_name.outputs.arch_name == 'aarch64' }}
uses: AdoptOpenJDK/install-jdk@v1
with:
impl: hotspot # or openj9
- version: '8'
+ version: '17'
architecture: aarch64
- name: 'Install software'
if: ${{ steps.get_arch_name.outputs.arch_name != 'aarch64' }}
@@ -224,8 +230,8 @@ jobs:
- uses: burrunan/gradle-cache-action@v1
name: Build pgjdbc
with:
- read-only: ${{ matrix.os == 'self-hosted' }}
- job-id: gss-jdk8
+ read-only: false
+ job-id: gss-jdk17
arguments: publishToMavenLocal -Ppgjdbc.version=1.0.0-dev-master -PskipJavadoc
- name: Run tests
run: |
diff --git a/build.gradle.kts b/build.gradle.kts
index dd89657916..7d8462a3c8 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -14,6 +14,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 {
@@ -66,6 +68,10 @@ val skipJavadoc by props()
val skipForbiddenApis by props()
val enableMavenLocal by props()
val enableGradleMetadata by props()
+// Java version to compile via toolchain; 0 = the JVM running Gradle
+val jdkBuildVersion = props.int("jdkBuildVersion", 17)
+// Java version to run tests via toolchain; 0 = reuse 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("")
@@ -354,7 +360,13 @@ allprojects {
}
// javadoc: error - The code being documented uses modules but the packages
// defined in https://docs.oracle.com/javase/9/docs/api/ are in the unnamed module
- source = "1.8"
+ if (JavaVersion.current() >= JavaVersion.VERSION_1_9) {
+ // Document against the Java 8 API. --release also avoids deprecation-for-removal
+ // warnings (e.g. AccessController) that newer JDKs emit and -Xwerror turns fatal.
+ addStringOption("-release", "8")
+ } else {
+ source = "1.8"
+ }
docEncoding = "UTF-8"
charSet = "UTF-8"
encoding = "UTF-8"
@@ -363,7 +375,12 @@ allprojects {
header = "<b>PostgreSQL JDBC</b>"
bottom =
"Copyright © 1997-$lastEditYear PostgreSQL Global Development Group. All Rights Reserved."
- if (JavaVersion.current() >= JavaVersion.VERSION_1_9) {
+ // There are too many missing javadocs, so failing the build on missing comments is not an option
+ addBooleanOption("Xdoclint:all,-missing", true)
+ if (JavaVersion.current() >= JavaVersion.VERSION_17) {
+ // Java 17+ javadoc warns on the redirecting javase/9 element-list, so skip the external links
+ addBooleanOption("html5", true)
+ } else if (JavaVersion.current() >= JavaVersion.VERSION_1_9) {
addBooleanOption("html5", true)
links("https://docs.oracle.com/javase/9/docs/api/";)
} else {
@@ -375,15 +392,16 @@ allprojects {
}
plugins.withType<JavaPlugin> {
- configure<JavaPluginConvention> {
- sourceCompatibility = JavaVersion.VERSION_1_8
- targetCompatibility = JavaVersion.VERSION_1_8
- }
configure<JavaPluginExtension> {
withSourcesJar()
if (!skipJavadoc) {
withJavadocJar()
}
+ if (jdkBuildVersion != 0) {
+ toolchain {
+ languageVersion.set(JavaLanguageVersion.of(jdkBuildVersion))
+ }
+ }
}
val sourceSets: SourceSetContainer by project
@@ -535,8 +553,23 @@ allprojects {
configureEach<JavaCompile> {
options.encoding = "UTF-8"
+ // Target Java 8 bytecode without referencing Java 9+ API.
+ // --release is only understood by javac 9+, so skip it on JDK 8.
+ 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)
@@ -569,7 +602,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. The build JVM's java.* properties
+ // (java.home, java.version, ...) must not leak into a test JVM
+ // running on a different Java version selected via jdkTestVersion.
+ if (e.startsWith("pgjdbc.")) {
passProperty(e)
}
}
diff --git a/gradle.properties b/gradle.properties
index 73e33b2025..84fc5b3e0b 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -16,6 +16,12 @@ kotlin.parallel.tasks.in.project=true
# Release version can be generated by using -Prelease or -Prc=<int> arguments
pgjdbc.version=42.3.11
+# 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
@@ -26,7 +32,7 @@ pgjdbc.version=42.3.11
# publishGradleMetadata=true
# Plugins
-biz.aQute.bnd.builder.version=4.3.1
+biz.aQute.bnd.builder.version=6.3.1
com.github.autostyle.version=3.1
com.github.burrunan.s3-build-cache.version=1.1
com.github.johnrengelman.shadow.version=5.1.0
diff --git a/pgjdbc/reduced-pom.xml b/pgjdbc/reduced-pom.xml
index 084393e116..1107ad3e19 100644
--- a/pgjdbc/reduced-pom.xml
+++ b/pgjdbc/reduced-pom.xml
@@ -37,6 +37,8 @@
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
<maven-jar-plugin.version>2.6</maven-jar-plugin.version>
<maven-javadoc-plugin.version>3.0.1</maven-javadoc-plugin.version>
+ <!-- Overridden by the add-opens-jdk16 profile so System Stubs can mock env vars on JDK 16+ -->
+ <surefire.argLine>-Xmx1536m</surefire.argLine>
</properties>
<dependencies>
@@ -103,7 +105,7 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
- <argLine>-Xmx1536m</argLine>
+ <argLine>${surefire.argLine}</argLine>
<systemPropertyVariables>
<build.properties.relative.path>.</build.properties.relative.path>
</systemPropertyVariables>
@@ -214,5 +216,19 @@
</plugins>
</build>
</profile>
+ <!--
+ System Stubs mocks environment variables via reflection. JDK 16+ rejects that
+ unless java.base is opened; these options are invalid on Java 8, so they live in a
+ JDK 16+ profile rather than the default argLine.
+ -->
+ <profile>
+ <id>add-opens-jdk16</id>
+ <activation>
+ <jdk>[16,)</jdk>
+ </activation>
+ <properties>
+ <surefire.argLine>-Xmx1536m --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED</surefire.argLine>
+ </properties>
+ </profile>
</profiles>
</project>
diff --git a/test-gss/build.gradle b/test-gss/build.gradle
index 4c67cefafd..06590a84da 100644
--- a/test-gss/build.gradle
+++ b/test-gss/build.gradle
@@ -13,9 +13,9 @@ repositories {
}
dependencies {
- implementation('org.codehaus.groovy:groovy-all:2.5.12')
+ implementation('org.codehaus.groovy:groovy-all:3.0.11')
implementation(group: 'org.postgresql', name: 'postgresql', version: '1.0.0-dev-master-SNAPSHOT')
- testCompile group: 'junit', name: 'junit', version: '4.12'
+ testImplementation(group: 'junit', name: 'junit', version: '4.12')
}
application {
mainClassName = 'TestPostgres'
diff --git a/test-gss/gradle/wrapper/gradle-wrapper.properties b/test-gss/gradle/wrapper/gradle-wrapper.properties
index bff6aebb59..0d01abe8db 100644
--- a/test-gss/gradle/wrapper/gradle-wrapper.properties
+++ b/test-gss/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,5 @@
-#Fri Jun 05 15:24:44 EDT 2020
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.1-all.zip
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
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 #4151: build: 42.3 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