Skip to content

Commit 4ee263f

Browse files
authored
JDK 16 compatibility (#4677)
1 parent 8475fd7 commit 4ee263f

47 files changed

Lines changed: 665 additions & 189 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ checker/tests/nullness-extra/*.class
125125
checker/tests/nullness-extra/compat/Out.txt
126126
checker/tests/nullness-extra/compat/javax/annotation/Nullable.class
127127
checker/tests/nullness-extra/compat/lib/Lib.class
128+
checker/tests/nullness-extra/issue3597/testpkg/Issue3597A.class
129+
checker/tests/nullness-extra/issue3597/testpkg/Issue3597B.class
128130
checker/tests/nullness-extra/issue502/Issue502.class
129131
checker/tests/nullness-extra/issue502/Out.txt
130132
checker/tests/nullness-extra/issue594/Out.txt

azure-pipelines.yml

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,21 @@ jobs:
3434
fetchDepth: 25
3535
- bash: ./checker/bin-devel/test-cftests-junit.sh
3636
displayName: test-cftests-junit.sh
37+
- job: junit_tests_jdk16
38+
dependsOn:
39+
- junit_tests_jdk11
40+
- nonjunit_tests_jdk11
41+
- misc_jdk11
42+
- typecheck_jdk11
43+
pool:
44+
vmImage: 'ubuntu-latest'
45+
container: mdernst/cf-ubuntu-jdk16:latest
46+
timeoutInMinutes: 70
47+
steps:
48+
- checkout: self
49+
fetchDepth: 25
50+
- bash: ./checker/bin-devel/test-cftests-junit.sh
51+
displayName: test-cftests-junit.sh
3752
- job: nonjunit_tests_jdk8
3853
dependsOn:
3954
- junit_tests_jdk11
@@ -57,6 +72,20 @@ jobs:
5772
fetchDepth: 25
5873
- bash: ./checker/bin-devel/test-cftests-nonjunit.sh
5974
displayName: test-cftests-nonjunit.sh
75+
- job: nonjunit_tests_jdk16
76+
dependsOn:
77+
- junit_tests_jdk11
78+
- nonjunit_tests_jdk11
79+
- misc_jdk11
80+
- typecheck_jdk11
81+
pool:
82+
vmImage: 'ubuntu-latest'
83+
container: mdernst/cf-ubuntu-jdk16:latest
84+
steps:
85+
- checkout: self
86+
fetchDepth: 25
87+
- bash: ./checker/bin-devel/test-cftests-nonjunit.sh
88+
displayName: test-cftests-nonjunit.sh
6089
- job: inference_tests_jdk8
6190
dependsOn:
6291
- junit_tests_jdk11
@@ -80,6 +109,20 @@ jobs:
80109
fetchDepth: 25
81110
- bash: ./checker/bin-devel/test-cftests-inference.sh
82111
displayName: test-cftests-inference.sh
112+
- job: inference_tests_jdk16
113+
dependsOn:
114+
- junit_tests_jdk11
115+
- inference_tests_jdk11
116+
- misc_jdk11
117+
- typecheck_jdk11
118+
pool:
119+
vmImage: 'ubuntu-latest'
120+
container: mdernst/cf-ubuntu-jdk16:latest
121+
steps:
122+
- checkout: self
123+
fetchDepth: 25
124+
- bash: ./checker/bin-devel/test-cftests-inference.sh
125+
displayName: test-cftests-inference.sh
83126
- job: misc_jdk8
84127
## The dependsOn is commented out because misc_jdk8 sometimes fails when misc_jdk11 does not.
85128
# dependsOn:
@@ -104,6 +147,20 @@ jobs:
104147
fetchDepth: 1000
105148
- bash: ./checker/bin-devel/test-misc.sh
106149
displayName: test-misc.sh
150+
- job: misc_jdk16
151+
dependsOn:
152+
- junit_tests_jdk11
153+
- nonjunit_tests_jdk11
154+
- misc_jdk11
155+
- typecheck_jdk11
156+
pool:
157+
vmImage: 'ubuntu-latest'
158+
container: mdernst/cf-ubuntu-jdk16-plus:latest
159+
steps:
160+
- checkout: self
161+
fetchDepth: 1000
162+
- bash: ./checker/bin-devel/test-misc.sh
163+
displayName: test-misc.sh
107164
- job: typecheck_jdk8
108165
dependsOn:
109166
- junit_tests_jdk11
@@ -127,6 +184,20 @@ jobs:
127184
fetchDepth: 1000
128185
- bash: ./checker/bin-devel/test-typecheck.sh
129186
displayName: test-typecheck.sh
187+
- job: typecheck_jdk16
188+
dependsOn:
189+
- junit_tests_jdk11
190+
- nonjunit_tests_jdk11
191+
- misc_jdk11
192+
- typecheck_jdk11
193+
pool:
194+
vmImage: 'ubuntu-latest'
195+
container: mdernst/cf-ubuntu-jdk16-plus:latest
196+
steps:
197+
- checkout: self
198+
fetchDepth: 1000
199+
- bash: ./checker/bin-devel/test-typecheck.sh
200+
displayName: test-typecheck.sh
130201
- job: daikon_jdk8
131202
dependsOn:
132203
- junit_tests_jdk11
@@ -154,6 +225,24 @@ jobs:
154225
fetchDepth: 25
155226
- bash: ./checker/bin-devel/test-daikon.sh
156227
displayName: test-daikon.sh
228+
## Daikon does not yet support JDK 16. TODO: Make Daikon run under JDK 16.
229+
# - job: daikon_jdk16
230+
# dependsOn:
231+
# - junit_tests_jdk11
232+
# - nonjunit_tests_jdk11
233+
# - misc_jdk11
234+
# - typecheck_jdk11
235+
# # ## Commented to reduce latency and eliminate the "daikon_jdk11 -> daikon_jdk16" critical path.
236+
# # # - daikon_jdk11
237+
# pool:
238+
# vmImage: 'ubuntu-latest'
239+
# container: mdernst/cf-ubuntu-jdk16:latest
240+
# timeoutInMinutes: 70
241+
# steps:
242+
# - checkout: self
243+
# fetchDepth: 25
244+
# - bash: ./checker/bin-devel/test-daikon.sh
245+
# displayName: test-daikon.sh
157246
- job: guava_jdk8
158247
dependsOn:
159248
- junit_tests_jdk11
@@ -178,6 +267,21 @@ jobs:
178267
fetchDepth: 25
179268
- bash: ./checker/bin-devel/test-guava.sh
180269
displayName: test-guava.sh
270+
- job: guava_jdk16
271+
dependsOn:
272+
- junit_tests_jdk11
273+
- nonjunit_tests_jdk11
274+
- misc_jdk11
275+
- typecheck_jdk11
276+
- guava_jdk11
277+
pool:
278+
vmImage: 'ubuntu-latest'
279+
container: mdernst/cf-ubuntu-jdk16:latest
280+
steps:
281+
- checkout: self
282+
fetchDepth: 25
283+
- bash: ./checker/bin-devel/test-guava.sh
284+
displayName: test-guava.sh
181285
- job: plume_lib_jdk8
182286
dependsOn:
183287
- junit_tests_jdk11
@@ -202,6 +306,22 @@ jobs:
202306
fetchDepth: 25
203307
- bash: ./checker/bin-devel/test-plume-lib.sh
204308
displayName: test-plume-lib.sh
309+
- job: plume_lib_jdk16
310+
dependsOn:
311+
- junit_tests_jdk11
312+
- nonjunit_tests_jdk11
313+
- misc_jdk11
314+
- typecheck_jdk11
315+
- plume_lib_jdk11
316+
pool:
317+
vmImage: 'ubuntu-latest'
318+
container: mdernst/cf-ubuntu-jdk16:latest
319+
steps:
320+
- checkout: self
321+
fetchDepth: 25
322+
- bash: ./checker/bin-devel/test-plume-lib.sh
323+
displayName: test-plume-lib.sh
324+
## The downstream jobs are not currently needed because test-downstream.sh is empty.
205325
# - job: downstream_jdk8
206326
# dependsOn:
207327
# - junit_tests_jdk11
@@ -226,3 +346,18 @@ jobs:
226346
# fetchDepth: 25
227347
# - bash: ./checker/bin-devel/test-downstream.sh
228348
# displayName: test-downstream.sh
349+
# - job: downstream_jdk16
350+
# dependsOn:
351+
# - junit_tests_jdk11
352+
# - nonjunit_tests_jdk11
353+
# - misc_jdk11
354+
# - typecheck_jdk11
355+
# - downstream_jdk11
356+
# pool:
357+
# vmImage: 'ubuntu-latest'
358+
# container: mdernst/cf-ubuntu-jdk16:latest
359+
# steps:
360+
# - checkout: self
361+
# fetchDepth: 25
362+
# - bash: ./checker/bin-devel/test-downstream.sh
363+
# displayName: test-downstream.sh

build.gradle

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ ext {
2626
// On a Java 9+ JVM, use the host javac, default source/target, and required module flags.
2727
isJava8 = JavaVersion.current() == JavaVersion.VERSION_1_8
2828

29+
isJava16 = JavaVersion.current() == JavaVersion.VERSION_16
30+
2931
errorproneJavacVersion = '9+181-r4173-1'
3032

3133
parentDir = file("${rootDir}/../").absolutePath
@@ -58,6 +60,7 @@ switch (JavaVersion.current()) {
5860
break;
5961
case JavaVersion.VERSION_1_8:
6062
case JavaVersion.VERSION_11:
63+
case JavaVersion.VERSION_16:
6164
break; // Supported versions
6265
default:
6366
throw new GradleException("Build the Checker Framework with JDK 8 or JDK 11." +
@@ -354,8 +357,18 @@ def createCheckTypeTask(projectName, taskName, checker, args = []) {
354357
} else {
355358
options.fork = true
356359
options.forkOptions.jvmArgs += [
360+
// These are required in Java 16+ because the --illegal-access option is set to deny
361+
// by default. None of these packages are accessed via reflection, so the module
362+
// only needs to be exported, but not opened.
363+
"--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
364+
"--add-exports", "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
365+
"--add-exports", "jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
366+
"--add-exports", "jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED",
367+
"--add-exports", "jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
368+
"--add-exports", "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
369+
// Required because the Checker Framework reflectively accesses private members in com.sun.tools.javac.comp.
357370
"--add-opens", "jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED",
358-
]
371+
]
359372
}
360373
}
361374
}
@@ -662,6 +675,9 @@ subprojects {
662675
}
663676
args += "${formatScriptsHome}/check-google-java-format.py"
664677
args += getJavaFilesToFormat(project.name)
678+
// Since the scripts are downloaded from third-party Github, the environment variable
679+
// is the only way to add the necessary open:
680+
environment('JDK_JAVA_OPTIONS', '--add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED')
665681
}
666682
ignoreExitValue = true
667683
doLast {
@@ -819,7 +835,16 @@ subprojects {
819835
// uses the jdk.jdeps module.
820836
"-javacoptions:--add-modules jdk.jdeps",
821837
"-javacoptions:--add-exports=jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED",
838+
"-vmoptions:--add-opens=jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED",
839+
"-vmoptions:--add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
840+
"-vmoptions:--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
822841
"-vmoptions:--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED",
842+
"-vmoptions:--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED",
843+
"-vmoptions:--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
844+
"-vmoptions:--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED",
845+
"-vmoptions:--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED",
846+
"-vmoptions:--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
847+
"-vmoptions:--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
823848
]
824849
}
825850
if (project.name.is('framework')) {
@@ -923,7 +948,12 @@ subprojects {
923948
tasks.create(name: 'inferenceTests', group: 'Verification') {
924949
description 'Run inference tests.'
925950
if (project.name.is('checker')) {
926-
dependsOn('ainferTest', 'wpiManyTest', 'wpiPlumeLibTest')
951+
// TODO JDK16: Use this line instead of the following lines.
952+
// dependsOn('ainferTest', 'wpiManyTest', 'wpiPlumeLibTest')
953+
dependsOn('ainferTest', 'wpiPlumeLibTest')
954+
if (!isJava16) {
955+
dependsOn('wpiManyTest')
956+
}
927957
}
928958
}
929959

checker-util/src/main/java/org/checkerframework/checker/i18nformatter/util/I18nFormatUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ private static void makeFormat(int offsetNumber, @Nullable StringBuilder[] textS
300300
argumentIndices.add(argumentNumber);
301301

302302
// now get the format
303-
I18nConversionCategory category = null;
303+
final I18nConversionCategory category;
304304
if (segments[SEG_TYPE].length() != 0) {
305305
int type = findKeyword(segments[SEG_TYPE], TYPE_KEYWORDS);
306306
switch (type) {

checker/bin-devel/build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ version=$("$_java" -version 2>&1 | head -1 | cut -d'"' -f2 | sed '/^1\./s///' |
6969
if [[ "$version" -ge 9 ]]; then
7070
echo "Running: (cd ../jspecify/ && ./gradlew build)"
7171
# If failure, retry in case the failure was due to network lossage.
72-
(cd ../jspecify/ && ./gradlew build) || (sleep 60 && cd ../jspecify/ && ./gradlew build)
72+
(cd ../jspecify/ && export JDK_JAVA_OPTIONS='--add-opens jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED' && (./gradlew build || (sleep 60 && ./gradlew build)))
7373
echo "... done: (cd ../jspecify/ && ./gradlew build)"
7474
fi
7575

checker/bin-devel/test-plume-lib.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,6 @@ for PACKAGE in "${PACKAGES[@]}"; do
5151
echo "About to call ./gradlew --console=plain -PcfLocal compileJava"
5252
# Try twice in case of network lossage while downloading packages (e.g., from Maven Central).
5353
# A disadvantage is that if there is a real error in pluggable type-checking, this runs it twice
54-
# and puts a delays in between.
54+
# and puts a delay in between.
5555
(cd "${PACKAGEDIR}" && (./gradlew --console=plain -PcfLocal compileJava || (sleep 60 && ./gradlew --console=plain -PcfLocal compileJava)))
5656
done

checker/bin-devel/wpi-plumelib/test-wpi-plumelib.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ clean_compile_output() {
4545

4646
# Remove uninteresting output
4747
sed -i '/^warning: \[path\] bad path element /d' "$out"
48+
sed -i '/^.*warning: Option --illegal-access is deprecated and will be removed in a future release./d' "$out"
49+
sed -i '/^warning: \[options\] bootstrap class path not set/d' "$out"
50+
51+
# Remove warning count because it can differ between JDK 8 and later JDKs due to the bootstrap warning:
52+
sed -i '/^[0-9]* warning/d' "$out"
4853

4954
# Remove directory names and line numbers
5055
sed -i 's/^[^ ]*\///' "$out"

checker/bin/wpi-many.sh

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ else
6565
has_java11="yes"
6666
fi
6767

68+
# shellcheck disable=SC2153 # testing for JAVA16_HOME, not a typo of JAVA_HOME
69+
if [ "x${JAVA16_HOME}" = "x" ]; then
70+
has_java16="no"
71+
else
72+
has_java16="yes"
73+
fi
74+
6875
if [ "${has_java_home}" = "yes" ]; then
6976
java_version=$("${JAVA_HOME}"/bin/java -version 2>&1 | head -1 | cut -d'"' -f2 | sed '/^1\./s///' | cut -d'.' -f1)
7077
if [ "${has_java8}" = "no" ] && [ "${java_version}" = 8 ]; then
@@ -75,6 +82,10 @@ if [ "${has_java_home}" = "yes" ]; then
7582
export JAVA11_HOME="${JAVA_HOME}"
7683
has_java11="yes"
7784
fi
85+
if [ "${has_java16}" = "no" ] && [ "${java_version}" = 16 ]; then
86+
export JAVA16_HOME="${JAVA_HOME}"
87+
has_java16="yes"
88+
fi
7889
fi
7990

8091
if [ "${has_java8}" = "yes" ] && [ ! -d "${JAVA8_HOME}" ]; then
@@ -87,8 +98,13 @@ if [ "${has_java11}" = "yes" ] && [ ! -d "${JAVA11_HOME}" ]; then
8798
exit 1
8899
fi
89100

90-
if [ "${has_java8}" = "no" ] && [ "${has_java11}" = "no" ]; then
91-
echo "No Java 8 or 11 JDKs found. At least one of JAVA_HOME, JAVA8_HOME, or JAVA11_HOME must be set."
101+
if [ "${has_java16}" = "yes" ] && [ ! -d "${JAVA16_HOME}" ]; then
102+
echo "JAVA16_HOME is set to a non-existent directory ${JAVA16_HOME}"
103+
exit 1
104+
fi
105+
106+
if [ "${has_java8}" = "no" ] && [ "${has_java11}" = "no" ] && [ "${has_java16}" = "no" ]; then
107+
echo "No Java 8, 11, or 16 JDKs found. At least one of JAVA_HOME, JAVA8_HOME, JAVA11_HOME, or JAVA16_HOME must be set."
92108
exit 1
93109
fi
94110

0 commit comments

Comments
 (0)