Let JacocoCoverageRunner identify the classpath on JDK 16+
The Unsafe-backed extraction of the classpath in
`JacocoCoverageRunner#getClassLoaderUrls` has to be adapted for JDK 16+
as the private `ucp` field on `AppClassLoader` has been moved to its
superclass.
With this commit, the existing coverage integration tests pass for the
JDK 17 toolchain.
Closes #15081.
PiperOrigin-RevId: 439518636
diff --git a/src/java_tools/junitrunner/java/com/google/testing/coverage/JacocoCoverageRunner.java b/src/java_tools/junitrunner/java/com/google/testing/coverage/JacocoCoverageRunner.java
index c466d49..b41fe31 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/coverage/JacocoCoverageRunner.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/coverage/JacocoCoverageRunner.java
@@ -398,8 +398,17 @@
field.setAccessible(true);
Unsafe unsafe = (Unsafe) field.get(null);
- // jdk.internal.loader.ClassLoaders.AppClassLoader.ucp
- Field ucpField = classLoader.getClass().getDeclaredField("ucp");
+ Field ucpField;
+ try {
+ // Java 9-15:
+ // jdk.internal.loader.ClassLoaders.AppClassLoader.ucp
+ ucpField = classLoader.getClass().getDeclaredField("ucp");
+ } catch (NoSuchFieldException e) {
+ // Java 16+:
+ // jdk.internal.loader.BuiltinClassLoader.ucp
+ // https://github.com/openjdk/jdk/commit/03a4df0acd103702e52dcd01c3f03fda4d7b04f5#diff-32cc12c0e3172fe5f2da1f65a75fa1cb920c39040d06323c83ad2c4d84e095aaL147
+ ucpField = classLoader.getClass().getSuperclass().getDeclaredField("ucp");
+ }
long ucpFieldOffset = unsafe.objectFieldOffset(ucpField);
Object ucpObject = unsafe.getObject(classLoader, ucpFieldOffset);
diff --git a/src/test/shell/bazel/BUILD b/src/test/shell/bazel/BUILD
index b195059..82e99e7 100644
--- a/src/test/shell/bazel/BUILD
+++ b/src/test/shell/bazel/BUILD
@@ -512,7 +512,8 @@
],
tags = ["no_windows"],
)
- for java_version in JAVA_VERSIONS_COVERAGE
+ # TODO: Update JAVA_VERSIONS_COVERAGE on the next java_tools release.
+ for java_version in JAVA_VERSIONS_COVERAGE + ("17",)
]
sh_test(