Skip to content

Commit

Permalink
Add tasks to run JDK 8 tests on JDK 11+ (#778)
Browse files Browse the repository at this point in the history
This PR adds tasks to additionally run certain test suites on JDK 8,
even when we are building on a JDK 11+ JVM. The approach is described
[here](https://jakewharton.com/build-on-latest-java-test-through-lowest-java/).
This moves us towards only supporting building NullAway on JDK 11+,
while still targeting Java 8 (so NullAway can still be used on JDK 8).
This will help us with keeping build tooling and dependencies up to
date, as more and more tools and plugins do not support running on JDK
8.

Specifically, we run the core NullAway tests and the tests from
`guava-recent-unit-tests` on JDK 8. We do _not_ run JarInfer tests, as
we intend to remove the ability to run JarInfer on JDK 8 (see #777).
Also, we only create the relevant test tasks when the Error Prone
version being used is 2.4.0 (compatible with Java 8). We have one CI
job, Java 11 + EP 2.4.0, that exercises this scenario. I confirmed
locally that when running the `testJdk8` tasks, the tests are running on
a JDK 8 JVM.

Additionally, the PR contains a minor tweak that allows
`publishToMavenLocal` to work when Gradle is run on JDK 11+.
  • Loading branch information
msridhar committed Jul 8, 2023
1 parent 18b6ab3 commit ec64e82
Show file tree
Hide file tree
Showing 14 changed files with 78 additions and 52 deletions.
2 changes: 0 additions & 2 deletions annotations/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ plugins {
id 'nullaway.jacoco-conventions'
}

sourceCompatibility = 1.8

dependencies {
}

Expand Down
17 changes: 5 additions & 12 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,11 @@ subprojects { project ->
}
}

// We target Java 11 when building on JDK 11+, but Java 8 when building on JDK 8, since
// EP 2.11.0+ requires Java 11
if (JavaVersion.current() >= JavaVersion.VERSION_11) {
tasks.withType(JavaCompile) {
java.sourceCompatibility = "11"
java.targetCompatibility = "11"
}
} else {
tasks.withType(JavaCompile) {
java.sourceCompatibility = "1.8"
java.targetCompatibility = "1.8"
}
// Target JDK 8. We need to use the older sourceCompatibility / targetCompatibility settings to get
// the build to work on JDK 11+. Once we stop supporting JDK 8, switch to using the javac "release" option
tasks.withType(JavaCompile) {
java.sourceCompatibility = "1.8"
java.targetCompatibility = "1.8"
}

// Ensure we are running on Java 8 whenever publishing to remote repos
Expand Down
27 changes: 27 additions & 0 deletions guava-recent-unit-tests/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,30 @@ test {
]
}
}

if (JavaVersion.current() >= JavaVersion.VERSION_11) {
// Create a task to test on JDK 8
def jdk8Test = tasks.register("testJdk8", Test) {
onlyIf {
// Only if we are using a version of Error Prone compatible with JDK 8
deps.versions.errorProneApi == "2.4.0"
}

javaLauncher = javaToolchains.launcherFor {
languageVersion = JavaLanguageVersion.of(8)
}

description = "Runs the test suite on JDK 8"
group = LifecycleBasePlugin.VERIFICATION_GROUP

// Copy inputs from normal Test task.
def testTask = tasks.getByName("test")
classpath = testTask.classpath
testClassesDirs = testTask.testClassesDirs
jvmArgs "-Xbootclasspath/p:${configurations.errorproneJavac.asPath}"
}

tasks.named('check').configure {
dependsOn(jdk8Test)
}
}
2 changes: 0 additions & 2 deletions jar-infer/android-jarinfer-models-sdk28/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ plugins {
id "java-library"
}

sourceCompatibility = 1.8

repositories {
mavenCentral()
}
Expand Down
2 changes: 0 additions & 2 deletions jar-infer/android-jarinfer-models-sdk29/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ plugins {
id "java-library"
}

sourceCompatibility = 1.8

repositories {
mavenCentral()
}
Expand Down
2 changes: 0 additions & 2 deletions jar-infer/android-jarinfer-models-sdk30/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ plugins {
id "java-library"
}

sourceCompatibility = 1.8

repositories {
mavenCentral()
}
Expand Down
2 changes: 0 additions & 2 deletions jar-infer/android-jarinfer-models-sdk31/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ plugins {
id "java-library"
}

sourceCompatibility = 1.8

repositories {
mavenCentral()
}
Expand Down
1 change: 1 addition & 0 deletions jar-infer/jar-infer-cli/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ publishing {
project.tasks.named('publishShadowPublicationToMavenLocal').configure {
dependsOn 'sourcesJar'
dependsOn 'simpleJavadocJar'
dependsOn 'signMavenPublication'
}
}
}
2 changes: 0 additions & 2 deletions jar-infer/jar-infer-lib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ plugins {
id 'nullaway.jacoco-conventions'
}

sourceCompatibility = 1.8

repositories {
mavenCentral()
// uncomment if you want to use wala.dalvik or wala.scandroid
Expand Down
2 changes: 0 additions & 2 deletions jar-infer/test-android-lib-jarinfer/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@

apply plugin: 'com.android.library'

sourceCompatibility = 1.8

android {
compileSdkVersion deps.build.compileSdkVersion

Expand Down
62 changes: 45 additions & 17 deletions nullaway/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -101,25 +101,53 @@ test {
apply plugin: 'com.vanniktech.maven.publish'

if (JavaVersion.current() >= JavaVersion.VERSION_11) {
// Required on Java 11+ since Error Prone and NullAway access a bunch of
// JDK-internal APIs that are not exposed otherwise
tasks.withType(JavaCompile).configureEach {
options.compilerArgs += [
"--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
"--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED",
"--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
"--add-exports=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED",
"--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
"--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED",
"--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED",
"--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED",
"--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
"--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
"--add-exports=jdk.compiler/com.sun.source.tree=ALL-UNNAMED",
]
// These --add-exports arguments are required when targeting JDK 11+ since Error Prone and NullAway access a bunch of
// JDK-internal APIs that are not exposed otherwise. Since we currently target JDK 8, we do not need to pass the
// arguments, as encapsulation of JDK internals is not enforced on JDK 8. In fact, the arguments cause a compiler error
// when targeting JDK 8. Leaving commented so we can easily add them back once we target JDK 11.
// tasks.withType(JavaCompile).configureEach {
// options.compilerArgs += [
// "--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
// "--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED",
// "--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
// "--add-exports=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED",
// "--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
// "--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED",
// "--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED",
// "--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED",
// "--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
// "--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
// "--add-exports=jdk.compiler/com.sun.source.tree=ALL-UNNAMED",
// ]
// }

// Create a task to test on JDK 8
def jdk8Test = tasks.register("testJdk8", Test) {
onlyIf {
// Only if we are using a version of Error Prone compatible with JDK 8
deps.versions.errorProneApi == "2.4.0"
}

javaLauncher = javaToolchains.launcherFor {
languageVersion = JavaLanguageVersion.of(8)
}

description = "Runs the test suite on JDK 8"
group = LifecycleBasePlugin.VERIFICATION_GROUP

// Copy inputs from normal Test task.
def testTask = tasks.getByName("test")
classpath = testTask.classpath
testClassesDirs = testTask.testClassesDirs
jvmArgs "-Xbootclasspath/p:${configurations.errorproneJavac.asPath}"
}

tasks.named('check').configure {
dependsOn(jdk8Test)
}

// Create a task to build NullAway with NullAway checking enabled
// For some reason, this doesn't work on Java 8
// (For some reason, this doesn't work on Java 8)
tasks.register('buildWithNullAway', JavaCompile) {
onlyIf {
// We only do NullAway checks when compiling against the latest
Expand Down
3 changes: 0 additions & 3 deletions sample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ plugins {
id "java-library"
}

sourceCompatibility = "1.8"
targetCompatibility = "1.8"

dependencies {
annotationProcessor project(":nullaway")
annotationProcessor project(path: ":sample-library-model")
Expand Down
3 changes: 0 additions & 3 deletions test-java-lib-lombok/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ plugins {
id "java-library"
}

sourceCompatibility = "1.8"
targetCompatibility = "1.8"

dependencies {
annotationProcessor project(":nullaway")
annotationProcessor deps.test.lombok
Expand Down
3 changes: 0 additions & 3 deletions test-java-lib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ plugins {
id "java-library"
}

sourceCompatibility = "1.8"
targetCompatibility = "1.8"

dependencies {
annotationProcessor project(":nullaway")
implementation deps.build.jspecify
Expand Down

0 comments on commit ec64e82

Please sign in to comment.