From 3b5d10e2a1f4275e87f6b4fddf7910711a59e3a5 Mon Sep 17 00:00:00 2001
From: Ashley Scopes <73482956+ascopes@users.noreply.github.com>
Date: Tue, 20 Oct 2026 07:56:09 +0100
Subject: [PATCH 1/3] Deprecate Java 17 support now it is at end of life.
---
.github/workflows/build.yml | 29 +-----
java-compiler-testing/pom.xml | 82 +++++++---------
.../ascopes/jct/compilers/JctCompiler.java | 2 +-
.../compilers/impl/JavacJctCompilerImpl.java | 23 +----
.../ascopes/jct/utils/LoomPolyfill.java | 18 +---
.../src/main/java/module-info.java | 3 +
.../compilers/AbstractJctCompilerTest.java | 1 -
.../impl/JavacJctCompilerImplTest.java | 40 +++-----
.../ascopes/jct/utils/LoomPolyfillTest.java | 26 +----
.../impl/MemoryFileSystemProviderTest.java | 2 +-
pom.xml | 96 +++++++++----------
11 files changed, 115 insertions(+), 207 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index fbe83f61a..49b973026 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -23,38 +23,14 @@ jobs:
uses: actions/checkout@v7
###
- ### Lint scripts and configuration files.
+ ### Lint configuration files.
###
- #- name: Validate shell scripts
- # uses: ludeeus/action-shellcheck@master
- # if: ${{ ! cancelled() }}
- # with:
- # check_together: 'yes'
- # scandir: ./scripts
-
- name: Validate codecov.yml
shell: bash
if: ${{ ! cancelled() }}
run: curl -si --fail-with-body --data-binary @codecov.yml https://codecov.io/validate
- ###
- ### Lint GitHub Actions for issues.
- ###
-
- - name: Lint GitHub Actions
- shell: bash
- if: ${{ ! cancelled() }}
- run: >-
- docker run
- --rm
- --user "$(id -u "${USER}"):$(id -g "${USER}")"
- --volume "$(pwd):/repo"
- --workdir /repo
- rhysd/actionlint:latest
- -color
- -verbose
-
###
### Lint Java, export information about current environment for
### the next jobs to utilise.
@@ -86,14 +62,13 @@ jobs:
matrix:
os-name: [ubuntu-latest]
java-version:
- - 17 # LTS
- 21 # LTS
- 25 # LTS
include:
- os-name: windows-11-arm
java-version: 23 # Latest Temurin for ARM
- os-name: macos-latest
- java-version: 25 # LTS
+ java-version: 21
steps:
- name: Checkout repository
diff --git a/java-compiler-testing/pom.xml b/java-compiler-testing/pom.xml
index bbb5a2acd..f76d07691 100644
--- a/java-compiler-testing/pom.xml
+++ b/java-compiler-testing/pom.xml
@@ -22,7 +22,7 @@
For example, running this on JRE 19 would set the release to "19". + *
For example, running this on JRE 25 would set the release to "25". * *
This calls {@link #release(int)} internally. * diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/impl/JavacJctCompilerImpl.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/impl/JavacJctCompilerImpl.java index 8e9cd43d9..2d40db218 100644 --- a/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/impl/JavacJctCompilerImpl.java +++ b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/impl/JavacJctCompilerImpl.java @@ -34,9 +34,7 @@ */ public final class JavacJctCompilerImpl extends AbstractJctCompiler { - private static final int JAVA_8 = 8; private static final int JAVA_9 = 9; - private static final int JAVA_20 = 20; private static final String NAME = "JDK Compiler"; /** @@ -60,7 +58,7 @@ public JctFlagBuilderFactory getFlagBuilderFactory() { public Jsr199CompilerFactory getCompilerFactory() { // RequireNonNull to ensure the return result is non-null, since the ToolProvider // method is not annotated. - return () -> requireNonNull(ToolProvider.getSystemJavaCompiler(), + return () -> requireNonNull(ToolProvider.getSystemJavaCompiler(), "ToolProvider.getSystemJavaCompiler()"); } @@ -76,21 +74,10 @@ public JctFileManagerFactory getFileManagerFactory() { * @since 1.0.0 */ public static int getEarliestSupportedVersionInt() { - // Purposely do not hardcode members of the SourceVersion enum here other - // than utility methods, as this prevents compilation problems on various - // versions of the JDK when certain members are unavailable. - - @SuppressWarnings("EnumOrdinal") - var latestSupported = SourceVersion.latestSupported().ordinal(); - - if (latestSupported >= JAVA_20) { - // JDK 20 marks source-version 8 as obsolete, and emits compilation - // warnings that may break tests using "fail on warnings". To avoid this, - // disallow compiling Java 8 sources under Javac in JDK 20 or newer - return JAVA_9; - } - - return JAVA_8; + // JDK 20 marks source-version 8 as obsolete, and emits compilation + // warnings that may break tests using "fail on warnings". To avoid this, + // disallow compiling Java 8 sources under Javac in JDK 20 or newer + return JAVA_9; } /** diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/utils/LoomPolyfill.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/utils/LoomPolyfill.java index 8df7b6c70..8dc17d6ce 100644 --- a/java-compiler-testing/src/main/java/io/github/ascopes/jct/utils/LoomPolyfill.java +++ b/java-compiler-testing/src/main/java/io/github/ascopes/jct/utils/LoomPolyfill.java @@ -15,14 +15,15 @@ */ package io.github.ascopes.jct.utils; -import io.github.ascopes.jct.annotations.DeadCodeGenerated; - /** * Polyfill to enable supporting using the newer Thread APIs on newer platforms. * *
This specifically targets the new APIs introduced as part of Project Loom * in Java 19. * + *
This class is now suitable to be removed as we only target Java 21 and + * newer. + * * @author Ashley Scopes * @since 0.0.1 */ @@ -40,18 +41,9 @@ private LoomPolyfill() { * @param thread the thread to use. * @return the thread ID. */ - @DeadCodeGenerated public static long getThreadId(Thread thread) { - // Note: this test will never get 100% coverage on one JDK, because it totally depends on the - // JDK in use as to which code path runs. - try { - // Where possible, use the newer Loom API to fetch the thread ID. - var method = Thread.class.getDeclaredMethod("threadId"); - return (long) method.invoke(thread); - } catch (Exception ex) { - // Fall back to the old API (which is the only method prior to Java 19). - return thread.getId(); - } + // Now we baseline to Java 21, we don't have to use reflection to invoke this Java 19 API. + return thread.threadId(); } /** diff --git a/java-compiler-testing/src/main/java/module-info.java b/java-compiler-testing/src/main/java/module-info.java index d71767bf9..001badf19 100644 --- a/java-compiler-testing/src/main/java/module-info.java +++ b/java-compiler-testing/src/main/java/module-info.java @@ -24,6 +24,9 @@ *
For Java 11 support, please use version 4 of this library, which is still kept up to date. * Version 5 of this library only supports Java 17 onwards. * + *
For Java 17 support, please use version 6 of this library, which is still kept up to date. + * Version 7 of this library only supports Java 17 onwards. + * *
The Java Compiler Testing API has a number of facilities for assisting in testing
* anything related to the Java compiler. This includes Javac plugins and JSR-199 annotation
* processors.
diff --git a/java-compiler-testing/src/test/java/io/github/ascopes/jct/compilers/AbstractJctCompilerTest.java b/java-compiler-testing/src/test/java/io/github/ascopes/jct/compilers/AbstractJctCompilerTest.java
index 661eb2f89..8cb0a5738 100644
--- a/java-compiler-testing/src/test/java/io/github/ascopes/jct/compilers/AbstractJctCompilerTest.java
+++ b/java-compiler-testing/src/test/java/io/github/ascopes/jct/compilers/AbstractJctCompilerTest.java
@@ -552,7 +552,6 @@ void configureInvokesConfigurerOnTheCompiler() throws Throwable {
IllegalThreadStateException.class,
NoClassDefFoundError.class,
ClassNotFoundException.class,
- ThreadDeath.class,
})
@ParameterizedTest(name = "for exception of type {0}")
void configurePropagatesAnyException(Class extends Exception> exceptionCls) throws Throwable {
diff --git a/java-compiler-testing/src/test/java/io/github/ascopes/jct/compilers/impl/JavacJctCompilerImplTest.java b/java-compiler-testing/src/test/java/io/github/ascopes/jct/compilers/impl/JavacJctCompilerImplTest.java
index fdea9f91d..9d5df5de3 100644
--- a/java-compiler-testing/src/test/java/io/github/ascopes/jct/compilers/impl/JavacJctCompilerImplTest.java
+++ b/java-compiler-testing/src/test/java/io/github/ascopes/jct/compilers/impl/JavacJctCompilerImplTest.java
@@ -130,21 +130,13 @@ void compilersHaveNoDefaultAnnotationProcessorsSet() {
@DisplayName("the earliest supported version int has the expected value")
@CsvSource(useHeadersInDisplayName = true, value = {
"SourceVersion.latest(), expectedResult",
- " 9, 8",
- " 10, 8",
- " 11, 8",
- " 12, 8",
- " 13, 8",
- " 14, 8",
- " 15, 8",
- " 16, 8",
- " 17, 8",
- " 18, 8",
- " 19, 8",
- // JDK-20 marks Java 8 as obsolete, so we do not support it.
- // We default to Java 9 regardless in this case.
- " 20, 9",
" 21, 9",
+ " 22, 9",
+ " 23, 9",
+ " 24, 9",
+ " 25, 9",
+ " 26, 9",
+ " 27, 9",
})
@ParameterizedTest(name = "expect {1} when using Javac for JDK {0}")
@SuppressWarnings({"EnumOrdinal", "ResultOfMethodCallIgnored"})
@@ -166,22 +158,16 @@ void earliestSupportedVersionReturnsTheExpectedValue(int latest, int expectedRes
}
}
- @DisplayName("the earliest supported version int has the expected value")
+ @DisplayName("the latest supported version int has the expected value")
@CsvSource(useHeadersInDisplayName = true, value = {
"SourceVersion.latest(), expectedResult",
- " 9, 9",
- " 10, 10",
- " 11, 11",
- " 12, 12",
- " 13, 13",
- " 14, 14",
- " 15, 15",
- " 16, 16",
- " 17, 17",
- " 18, 18",
- " 19, 19",
- " 20, 20",
" 21, 21",
+ " 22, 22",
+ " 23, 23",
+ " 24, 24",
+ " 25, 25",
+ " 26, 26",
+ " 27, 27",
})
@ParameterizedTest(name = "expect {1} when using Javac for JDK {0}")
@SuppressWarnings({"EnumOrdinal", "ResultOfMethodCallIgnored"})
diff --git a/java-compiler-testing/src/test/java/io/github/ascopes/jct/utils/LoomPolyfillTest.java b/java-compiler-testing/src/test/java/io/github/ascopes/jct/utils/LoomPolyfillTest.java
index 6410d2582..8b6234e4e 100644
--- a/java-compiler-testing/src/test/java/io/github/ascopes/jct/utils/LoomPolyfillTest.java
+++ b/java-compiler-testing/src/test/java/io/github/ascopes/jct/utils/LoomPolyfillTest.java
@@ -26,8 +26,6 @@
import io.github.ascopes.jct.fixtures.UtilityClassTestTemplate;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.condition.EnabledForJreRange;
-import org.junit.jupiter.api.condition.JRE;
/**
* {@link LoomPolyfill} tests.
@@ -41,29 +39,9 @@ public Class> getTypeBeingTested() {
return LoomPolyfill.class;
}
- @DisplayName(".getThreadId(Thread) on JRE <= 18 calls .getId()")
- @EnabledForJreRange(max = JRE.JAVA_18)
+ @DisplayName(".getThreadId(Thread) calls .threadId()")
@Test
- void getThreadIdOnJre18AndOlderUsesThreadGetId() throws Throwable {
- // Given
- var expectedThreadId = Fixtures.someLong(1, Short.MAX_VALUE);
- var thread = mock(Thread.class);
- var getIdMethod = Thread.class.getDeclaredMethod("getId");
-
- when((long) getIdMethod.invoke(thread)).thenReturn(expectedThreadId);
-
- // When
- var actualThreadId = LoomPolyfill.getThreadId(thread);
-
- // Then
- assertThat(actualThreadId).isEqualTo(expectedThreadId);
- getIdMethod.invoke(verify(thread));
- }
-
- @DisplayName(".getThreadId(Thread) on JRE >= 19 calls .threadId()")
- @EnabledForJreRange(min = JRE.JAVA_19)
- @Test
- void getThreadIdOnJre19AndNewerUsesThreadId() throws Throwable {
+ void getThreadIdUsesThreadId() throws Throwable {
// Given
var expectedThreadId = Fixtures.someLong(1, Short.MAX_VALUE);
var thread = mock(Thread.class);
diff --git a/java-compiler-testing/src/test/java/io/github/ascopes/jct/workspaces/impl/MemoryFileSystemProviderTest.java b/java-compiler-testing/src/test/java/io/github/ascopes/jct/workspaces/impl/MemoryFileSystemProviderTest.java
index dff7f2075..9ed6b1571 100644
--- a/java-compiler-testing/src/test/java/io/github/ascopes/jct/workspaces/impl/MemoryFileSystemProviderTest.java
+++ b/java-compiler-testing/src/test/java/io/github/ascopes/jct/workspaces/impl/MemoryFileSystemProviderTest.java
@@ -227,7 +227,7 @@ void providerReturnsHandlerForMemoryProtocol(String urlString) throws MalformedU
@ValueSource(strings = {
"file://foo/bar/baz",
"jar:file://foo/bar/baz.jar!/Bork.class",
- "jrt:",
+ "jrt:/",
})
@ParameterizedTest(name = "for URL {0}")
void providerReturnsNullHandlerForOtherProtocol(String urlString) throws MalformedURLException {
diff --git a/pom.xml b/pom.xml
index a9aad8b18..30476e86c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@