[build] Java 25 support (#8775)

Commands v3 had a few changes due to the upgrade:
- Java 24 removed the Pinned: MONITOR IllegalStateException when
yielding in a synchronized block, so we no longer need to special case
for it
- Lambda method name generation was tweaked, requiring tests to be
updated
- Bazel java_rules needed to be bumped to support Java 25

Closes #8425
This commit is contained in:
Sam Carlberg
2026-04-17 00:02:17 -04:00
committed by GitHub
parent f96ded6909
commit 628ba1458f
16 changed files with 32 additions and 48 deletions

View File

@@ -9,10 +9,10 @@ common --enable_workspace
build --experimental_cc_static_library
build --experimental_cc_shared_library
build --java_language_version=21
build --java_runtime_version=remotejdk_21
build --tool_java_language_version=21
build --tool_java_runtime_version=remotejdk_21
build --java_language_version=25
build --java_runtime_version=remotejdk_25
build --tool_java_language_version=25
build --tool_java_runtime_version=remotejdk_25
test --test_output=errors
test --test_verbose_timeout_warnings

View File

@@ -36,7 +36,7 @@ jobs:
- uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: 21
java-version: 25
- name: Install sccache
uses: mozilla-actions/sccache-action@v0.0.9

View File

@@ -145,7 +145,7 @@ jobs:
- uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: 21
java-version: 25
architecture: ${{ matrix.architecture }}
- name: Import Developer ID Certificate
uses: wpilibsuite/import-signing-certificate@v3
@@ -325,7 +325,7 @@ jobs:
(github.ref == 'refs/heads/2027' || startsWith(github.ref, 'refs/tags/v2027'))
with:
distribution: 'temurin'
java-version: 21
java-version: 25
- name: Combine (2027)
if: |
github.repository == 'wpilibsuite/allwpilib' &&

View File

@@ -115,7 +115,7 @@ jobs:
- uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: 21
java-version: 25
architecture: ${{ matrix.architecture }}
- name: Import Developer ID Certificate
uses: wpilibsuite/import-signing-certificate@v3

View File

@@ -21,7 +21,7 @@ bazel_dep(name = "bazel_features", version = "1.33.0")
bazel_dep(name = "aspect_bazel_lib", version = "2.14.0")
bazel_dep(name = "bazel_skylib", version = "1.8.2")
bazel_dep(name = "platforms", version = "1.0.0")
bazel_dep(name = "rules_java", version = "8.14.0")
bazel_dep(name = "rules_java", version = "8.16.1")
bazel_dep(name = "rules_python", version = "1.7.0")
bazel_dep(name = "rules_pycross", version = "0.8.1")

9
MODULE.bazel.lock generated
View File

@@ -12,7 +12,8 @@
"https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16",
"https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1",
"https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215",
"https://bcr.bazel.build/modules/abseil-cpp/20250512.1/source.json": "d725d73707d01bb46ab3ca59ba408b8e9bd336642ca77a2269d4bfb8bbfd413d",
"https://bcr.bazel.build/modules/abseil-cpp/20250814.0/MODULE.bazel": "c43c16ca2c432566cdb78913964497259903ebe8fb7d9b57b38e9f1425b427b8",
"https://bcr.bazel.build/modules/abseil-cpp/20250814.0/source.json": "b88bff599ceaf0f56c264c749b1606f8485cec3b8c38ba30f88a4df9af142861",
"https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896",
"https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85",
"https://bcr.bazel.build/modules/apple_support/1.23.1/MODULE.bazel": "53763fed456a968cf919b3240427cf3a9d5481ec5466abc9d5dc51bc70087442",
@@ -49,6 +50,7 @@
"https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917",
"https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d",
"https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b",
"https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6",
"https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67",
"https://bcr.bazel.build/modules/bazel_skylib/1.8.2/source.json": "34a3c8bcf233b835eb74be9d628899bb32999d3e0eadef1947a0a562a2b16ffb",
"https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84",
@@ -112,9 +114,11 @@
"https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5",
"https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513",
"https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8",
"https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c",
"https://bcr.bazel.build/modules/rules_cc/0.2.13/MODULE.bazel": "eecdd666eda6be16a8d9dc15e44b5c75133405e820f620a234acc4b1fdc5aa37",
"https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8",
"https://bcr.bazel.build/modules/rules_cc/0.2.14/source.json": "55d0a4587c5592fad350f6e698530f4faf0e7dd15e69d43f8d87e220c78bea54",
"https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642",
"https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6",
"https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8",
"https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74",
@@ -129,7 +133,8 @@
"https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2",
"https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe",
"https://bcr.bazel.build/modules/rules_java/8.14.0/MODULE.bazel": "717717ed40cc69994596a45aec6ea78135ea434b8402fb91b009b9151dd65615",
"https://bcr.bazel.build/modules/rules_java/8.14.0/source.json": "8a88c4ca9e8759da53cddc88123880565c520503321e2566b4e33d0287a3d4bc",
"https://bcr.bazel.build/modules/rules_java/8.16.1/MODULE.bazel": "0f20b1cecaa8e52f60a8f071e59a20b4e3b9a67f6c56c802ea256f6face692d3",
"https://bcr.bazel.build/modules/rules_java/8.16.1/source.json": "072f8d11264edc499621be2dc9ea01d6395db5aa6f8799c034ae01a3e857f2e4",
"https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017",
"https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939",
"https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2",

View File

@@ -34,7 +34,7 @@ By default, all libraries get built with a default CMake setup. The libraries ar
OpenCV needs to be findable by CMake. On systems like the Jetson, this is installed by default. Otherwise, you will need to build OpenCV from source and install it.
If you want JNI and Java, you will need a JDK of at least version 21 installed. In addition, you need a `JAVA_HOME` environment variable set properly and set to the JDK directory.
If you want JNI and Java, you will need a JDK of at least version 25 installed. In addition, you need a `JAVA_HOME` environment variable set properly and set to the JDK directory.
If you are building with unit tests or simulation modules, you will also need an Internet connection for the initial setup process, as CMake will clone google-test and imgui from GitHub.

View File

@@ -42,11 +42,11 @@ Using Gradle makes building WPILib very straightforward. It only has a few depen
## Requirements
- [JDK 21](https://adoptium.net/temurin/releases/?version=21)
- [JDK 25](https://adoptium.net/temurin/releases/?version=25)
- Note that the JRE is insufficient; the full JDK is required
- On Ubuntu, run `sudo apt install openjdk-21-jdk`
- On Windows, install the JDK 21 .msi from the link above
- On macOS, install the JDK 21 .pkg from the link above
- On Ubuntu, run `sudo apt install openjdk-25-jdk`
- On Windows, install the JDK 25 .msi from the link above
- On macOS, install the JDK 25 .pkg from the link above
- C++ compiler
- On Linux, install GCC 11 or greater
- On Windows, install [Visual Studio Community 2022](https://visualstudio.microsoft.com/vs/community/) and select the C++ programming language during installation (Gradle can't use the build tools for Visual Studio)

View File

@@ -120,8 +120,8 @@ subprojects {
plugins.withType(JavaPlugin) {
java {
sourceCompatibility = 21
targetCompatibility = 21
sourceCompatibility = 25
targetCompatibility = 25
}
}

View File

@@ -48,24 +48,7 @@ public final class Coroutine {
public boolean yield() {
requireMounted();
try {
return m_backingContinuation.yield();
} catch (IllegalStateException e) {
if ("Pinned: MONITOR".equals(e.getMessage())) {
// Raised when a continuation yields inside a synchronized block or method:
// https://github.com/openjdk/jdk/blob/jdk-21%2B35/src/java.base/share/classes/jdk/internal/vm/Continuation.java#L396-L402
// Note: Not a thing in Java 24+
// Rethrow with an error message that's more helpful for our users
throw new IllegalStateException(
"Coroutine.yield() cannot be called inside a synchronized block or method. "
+ "Consider using a Lock instead of synchronized, "
+ "or rewrite your code to avoid locks and mutexes altogether.",
e);
} else {
// rethrow
throw e;
}
}
return m_backingContinuation.yield();
}
/**

View File

@@ -58,13 +58,8 @@ class CoroutineTest extends CommandTestBase {
.named("Yield In Synchronized Block");
m_scheduler.schedule(yieldInSynchronized);
var error = assertThrows(IllegalStateException.class, m_scheduler::run);
assertEquals(
"Coroutine.yield() cannot be called inside a synchronized block or method. "
+ "Consider using a Lock instead of synchronized, "
+ "or rewrite your code to avoid locks and mutexes altogether.",
error.getMessage());
m_scheduler.run();
assertEquals(1, i.get());
}
@Test

View File

@@ -88,8 +88,8 @@ class SchedulerErrorHandlingTests extends CommandTestBase {
// user code trace for where the command was scheduled (the `.onTrue()` line)
assertEquals("=== Command Binding Trace ===", stackTrace[nestedIndex + 2].getClassName());
assertEquals("lambda$nestedErrorDetection$4", stackTrace[nestedIndex + 3].getMethodName());
assertEquals("lambda$nestedErrorDetection$5", stackTrace[nestedIndex + 4].getMethodName());
assertEquals("lambda$nestedErrorDetection$1", stackTrace[nestedIndex + 3].getMethodName());
assertEquals("lambda$nestedErrorDetection$0", stackTrace[nestedIndex + 4].getMethodName());
assertEquals("nestedErrorDetection", stackTrace[nestedIndex + 5].getMethodName());
}

View File

@@ -158,7 +158,7 @@ configurations {
task generateJavaDocs(type: Javadoc) {
classpath += project(":wpilibj").sourceSets.main.compileClasspath
options.links("https://docs.oracle.com/en/java/javase/21/docs/api/")
options.links("https://docs.oracle.com/en/java/javase/25/docs/api/")
// workaround for opencv site blocking javadoc tool. If the link is changed,
// docs/opencv/element-list must be redownloaded
options.linksOffline("https://docs.opencv.org/4.10.0/javadoc/", "opencv")

View File

@@ -37,7 +37,7 @@ import org.wpilib.epilogue.Logged;
import org.wpilib.epilogue.NotLogged;
@SupportedAnnotationTypes({"org.wpilib.epilogue.CustomLoggerFor", "org.wpilib.epilogue.Logged"})
@SupportedSourceVersion(SourceVersion.RELEASE_21)
@SupportedSourceVersion(SourceVersion.RELEASE_25)
public class AnnotationProcessor extends AbstractProcessor {
private static final String kCustomLoggerFqn = "org.wpilib.epilogue.CustomLoggerFor";
private static final String kClassSpecificLoggerFqn =

View File

@@ -106,7 +106,7 @@ configurations {
tasks.withType(JavaCompile).configureEach {
options.compilerArgs = [
'--release',
'21',
'25',
'-encoding',
'UTF8',
"-Werror",

View File

@@ -76,6 +76,7 @@ public final class RuntimeLoader {
* @param libraryName the name of the library to load.
* @throws IOException if the library fails to load
*/
@SuppressWarnings("restricted")
public static void loadLibrary(String libraryName) throws IOException {
try {
System.loadLibrary(libraryName);